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

Side by Side Diff: src/lithium.h

Issue 14639008: Allow more virtual registers to be encoded in LUnallocated. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 7 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
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/lithium.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 class KindField : public BitField<Kind, 0, kKindFieldWidth> { }; 85 class KindField : public BitField<Kind, 0, kKindFieldWidth> { };
86 86
87 LOperand(Kind kind, int index) { ConvertTo(kind, index); } 87 LOperand(Kind kind, int index) { ConvertTo(kind, index); }
88 88
89 unsigned value_; 89 unsigned value_;
90 }; 90 };
91 91
92 92
93 class LUnallocated: public LOperand { 93 class LUnallocated: public LOperand {
94 public: 94 public:
95 enum Policy { 95 enum BasicPolicy {
96 FIXED_SLOT,
97 EXTENDED_POLICY
98 };
99
100 enum ExtendedPolicy {
96 NONE, 101 NONE,
97 ANY, 102 ANY,
98 FIXED_REGISTER, 103 FIXED_REGISTER,
99 FIXED_DOUBLE_REGISTER, 104 FIXED_DOUBLE_REGISTER,
100 FIXED_SLOT,
101 MUST_HAVE_REGISTER, 105 MUST_HAVE_REGISTER,
102 WRITABLE_REGISTER, 106 WRITABLE_REGISTER,
103 SAME_AS_FIRST_INPUT 107 SAME_AS_FIRST_INPUT
104 }; 108 };
105 109
106 // Lifetime of operand inside the instruction. 110 // Lifetime of operand inside the instruction.
107 enum Lifetime { 111 enum Lifetime {
108 // USED_AT_START operand is guaranteed to be live only at 112 // USED_AT_START operand is guaranteed to be live only at
109 // instruction start. Register allocator is free to assign the same register 113 // instruction start. Register allocator is free to assign the same register
110 // to some other operand used inside instruction (i.e. temporary or 114 // to some other operand used inside instruction (i.e. temporary or
111 // output). 115 // output).
112 USED_AT_START, 116 USED_AT_START,
113 117
114 // USED_AT_END operand is treated as live until the end of 118 // USED_AT_END operand is treated as live until the end of
115 // instruction. This means that register allocator will not reuse it's 119 // instruction. This means that register allocator will not reuse it's
116 // register for any other operand inside instruction. 120 // register for any other operand inside instruction.
117 USED_AT_END 121 USED_AT_END
118 }; 122 };
119 123
120 explicit LUnallocated(Policy policy) : LOperand(UNALLOCATED, 0) { 124 explicit LUnallocated(ExtendedPolicy policy) : LOperand(UNALLOCATED, 0) {
121 Initialize(policy, 0, USED_AT_END); 125 value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
126 value_ |= ExtendedPolicyField::encode(policy);
127 value_ |= LifetimeField::encode(USED_AT_END);
122 } 128 }
123 129
124 LUnallocated(Policy policy, int fixed_index) : LOperand(UNALLOCATED, 0) { 130 LUnallocated(BasicPolicy policy, int index) : LOperand(UNALLOCATED, 0) {
125 Initialize(policy, fixed_index, USED_AT_END); 131 ASSERT(policy == FIXED_SLOT);
132 value_ |= BasicPolicyField::encode(policy);
133 value_ |= index << FixedSlotIndexField::kShift;
134 ASSERT(this->fixed_slot_index() == index);
126 } 135 }
127 136
128 LUnallocated(Policy policy, Lifetime lifetime) : LOperand(UNALLOCATED, 0) { 137 LUnallocated(ExtendedPolicy policy, int index) : LOperand(UNALLOCATED, 0) {
129 Initialize(policy, 0, lifetime); 138 ASSERT(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER);
139 value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
140 value_ |= ExtendedPolicyField::encode(policy);
141 value_ |= LifetimeField::encode(USED_AT_END);
142 value_ |= FixedRegisterField::encode(index);
130 } 143 }
131 144
132 // The superclass has a KindField. Some policies have a signed fixed 145 LUnallocated(ExtendedPolicy policy, Lifetime lifetime)
133 // index in the upper bits. 146 : LOperand(UNALLOCATED, 0) {
134 static const int kPolicyWidth = 3; 147 value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
135 static const int kLifetimeWidth = 1; 148 value_ |= ExtendedPolicyField::encode(policy);
136 static const int kVirtualRegisterWidth = 15; 149 value_ |= LifetimeField::encode(lifetime);
137
138 static const int kPolicyShift = kKindFieldWidth;
139 static const int kLifetimeShift = kPolicyShift + kPolicyWidth;
140 static const int kVirtualRegisterShift = kLifetimeShift + kLifetimeWidth;
141 static const int kFixedIndexShift =
142 kVirtualRegisterShift + kVirtualRegisterWidth;
143 static const int kFixedIndexWidth = 32 - kFixedIndexShift;
144 STATIC_ASSERT(kFixedIndexWidth > 5);
145
146 class PolicyField : public BitField<Policy, kPolicyShift, kPolicyWidth> { };
147
148 class LifetimeField
149 : public BitField<Lifetime, kLifetimeShift, kLifetimeWidth> {
150 };
151
152 class VirtualRegisterField
153 : public BitField<unsigned,
154 kVirtualRegisterShift,
155 kVirtualRegisterWidth> {
156 };
157
158 static const int kMaxVirtualRegisters = 1 << kVirtualRegisterWidth;
159 static const int kMaxFixedIndex = (1 << (kFixedIndexWidth - 1)) - 1;
160 static const int kMinFixedIndex = -(1 << (kFixedIndexWidth - 1));
161
162 bool HasAnyPolicy() const {
163 return policy() == ANY;
164 }
165 bool HasFixedPolicy() const {
166 return policy() == FIXED_REGISTER ||
167 policy() == FIXED_DOUBLE_REGISTER ||
168 policy() == FIXED_SLOT;
169 }
170 bool HasRegisterPolicy() const {
171 return policy() == WRITABLE_REGISTER || policy() == MUST_HAVE_REGISTER;
172 }
173 bool HasSameAsInputPolicy() const {
174 return policy() == SAME_AS_FIRST_INPUT;
175 }
176 Policy policy() const { return PolicyField::decode(value_); }
177 void set_policy(Policy policy) {
178 value_ = PolicyField::update(value_, policy);
179 }
180 int fixed_index() const {
181 return static_cast<int>(value_) >> kFixedIndexShift;
182 }
183
184 int virtual_register() const {
185 return VirtualRegisterField::decode(value_);
186 }
187
188 void set_virtual_register(unsigned id) {
189 value_ = VirtualRegisterField::update(value_, id);
190 } 150 }
191 151
192 LUnallocated* CopyUnconstrained(Zone* zone) { 152 LUnallocated* CopyUnconstrained(Zone* zone) {
193 LUnallocated* result = new(zone) LUnallocated(ANY); 153 LUnallocated* result = new(zone) LUnallocated(ANY);
194 result->set_virtual_register(virtual_register()); 154 result->set_virtual_register(virtual_register());
195 return result; 155 return result;
196 } 156 }
197 157
198 static LUnallocated* cast(LOperand* op) { 158 static LUnallocated* cast(LOperand* op) {
199 ASSERT(op->IsUnallocated()); 159 ASSERT(op->IsUnallocated());
200 return reinterpret_cast<LUnallocated*>(op); 160 return reinterpret_cast<LUnallocated*>(op);
201 } 161 }
202 162
203 bool IsUsedAtStart() { 163 // The encoding used for LUnallocated operands depends on the policy that is
204 return LifetimeField::decode(value_) == USED_AT_START; 164 // stored within the operand. The FIXED_SLOT policy uses a compact encoding
165 // because it accommodates a larger pay-load.
166 //
167 // For FIXED_SLOT policy:
168 // +------------------------------------------+
169 // | slot_index | vreg | 0 | 001 |
170 // +------------------------------------------+
171 //
172 // For all other (extended) policies:
173 // +------------------------------------------+
174 // | reg_index | L | PPP | vreg | 1 | 001 | L ... Lifetime
175 // +------------------------------------------+ P ... Policy
176 //
177 // The slot index is a signed value which requires us to decode it manually
178 // instead of using the BitField utility class.
179
180 // The superclass has a KindField.
181 STATIC_ASSERT(kKindFieldWidth == 3);
182
183 // BitFields for all unallocated operands.
184 class BasicPolicyField : public BitField<BasicPolicy, 3, 1> {};
185 // TODO(mstarzinger): Bump this from 15 bit to 18 bit in a follow-up CL.
186 class VirtualRegisterField : public BitField<unsigned, 4, 15> {};
187
188 // BitFields specific to BasicPolicy::FIXED_SLOT.
189 class FixedSlotIndexField : public BitField<int, 22, 10> {};
190
191 // BitFields specific to BasicPolicy::EXTENDED_POLICY.
192 class ExtendedPolicyField : public BitField<ExtendedPolicy, 22, 3> {};
193 class LifetimeField : public BitField<Lifetime, 25, 1> {};
194 class FixedRegisterField : public BitField<int, 26, 6> {};
195
196 static const int kMaxVirtualRegisters = VirtualRegisterField::kMax + 1;
197 static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize;
198 static const int kMaxFixedSlotIndex = (1 << (kFixedSlotIndexWidth - 1)) - 1;
199 static const int kMinFixedSlotIndex = -(1 << (kFixedSlotIndexWidth - 1));
200
201 // Predicates for the operand policy.
202 bool HasAnyPolicy() const {
203 return basic_policy() == EXTENDED_POLICY &&
204 extended_policy() == ANY;
205 }
206 bool HasFixedPolicy() const {
207 return basic_policy() == FIXED_SLOT ||
208 extended_policy() == FIXED_REGISTER ||
209 extended_policy() == FIXED_DOUBLE_REGISTER;
210 }
211 bool HasRegisterPolicy() const {
212 return basic_policy() == EXTENDED_POLICY && (
213 extended_policy() == WRITABLE_REGISTER ||
214 extended_policy() == MUST_HAVE_REGISTER);
215 }
216 bool HasSameAsInputPolicy() const {
217 return basic_policy() == EXTENDED_POLICY &&
218 extended_policy() == SAME_AS_FIRST_INPUT;
219 }
220 bool HasFixedSlotPolicy() const {
221 return basic_policy() == FIXED_SLOT;
222 }
223 bool HasFixedRegisterPolicy() const {
224 return basic_policy() == EXTENDED_POLICY &&
225 extended_policy() == FIXED_REGISTER;
226 }
227 bool HasFixedDoubleRegisterPolicy() const {
228 return basic_policy() == EXTENDED_POLICY &&
229 extended_policy() == FIXED_DOUBLE_REGISTER;
230 }
231 bool HasWritableRegisterPolicy() const {
232 return basic_policy() == EXTENDED_POLICY &&
233 extended_policy() == WRITABLE_REGISTER;
205 } 234 }
206 235
207 private: 236 // [basic_policy]: Distinguish between FIXED_SLOT and all other policies.
208 void Initialize(Policy policy, int fixed_index, Lifetime lifetime) { 237 BasicPolicy basic_policy() const {
209 value_ |= PolicyField::encode(policy); 238 return BasicPolicyField::decode(value_);
210 value_ |= LifetimeField::encode(lifetime); 239 }
211 value_ |= fixed_index << kFixedIndexShift; 240
212 ASSERT(this->fixed_index() == fixed_index); 241 // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy.
242 ExtendedPolicy extended_policy() const {
243 ASSERT(basic_policy() == EXTENDED_POLICY);
244 return ExtendedPolicyField::decode(value_);
245 }
246
247 // [fixed_slot_index]: Only for FIXED_SLOT.
248 int fixed_slot_index() const {
249 ASSERT(HasFixedSlotPolicy());
250 return static_cast<int>(value_) >> FixedSlotIndexField::kShift;
251 }
252
253 // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER.
254 int fixed_register_index() const {
255 ASSERT(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy());
256 return FixedRegisterField::decode(value_);
257 }
258
259 // [virtual_register]: The virtual register ID for this operand.
260 int virtual_register() const {
261 return VirtualRegisterField::decode(value_);
262 }
263 void set_virtual_register(unsigned id) {
264 value_ = VirtualRegisterField::update(value_, id);
265 }
266
267 // [lifetime]: Only for non-FIXED_SLOT.
268 bool IsUsedAtStart() {
269 ASSERT(basic_policy() == EXTENDED_POLICY);
270 return LifetimeField::decode(value_) == USED_AT_START;
213 } 271 }
214 }; 272 };
215 273
216 274
217 class LMoveOperands BASE_EMBEDDED { 275 class LMoveOperands BASE_EMBEDDED {
218 public: 276 public:
219 LMoveOperands(LOperand* source, LOperand* destination) 277 LMoveOperands(LOperand* source, LOperand* destination)
220 : source_(source), destination_(destination) { 278 : source_(source), destination_(destination) {
221 } 279 }
222 280
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 NUMBER_CANDIDATE_IS_SMI, 772 NUMBER_CANDIDATE_IS_SMI,
715 NUMBER_CANDIDATE_IS_SMI_OR_HOLE, 773 NUMBER_CANDIDATE_IS_SMI_OR_HOLE,
716 NUMBER_CANDIDATE_IS_SMI_CONVERT_HOLE, 774 NUMBER_CANDIDATE_IS_SMI_CONVERT_HOLE,
717 NUMBER_CANDIDATE_IS_ANY_TAGGED 775 NUMBER_CANDIDATE_IS_ANY_TAGGED
718 }; 776 };
719 777
720 778
721 } } // namespace v8::internal 779 } } // namespace v8::internal
722 780
723 #endif // V8_LITHIUM_H_ 781 #endif // V8_LITHIUM_H_
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/lithium.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698