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

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 2891713002: Cleanup: Make CheckClassId instruction more general so it (Closed)
Patch Set: Feedback from Martin Created 3 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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.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 (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 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/bootstrap.h" 8 #include "vm/bootstrap.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/constant_propagator.h" 10 #include "vm/constant_propagator.h"
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 } 137 }
138 138
139 139
140 bool Value::Equals(Value* other) const { 140 bool Value::Equals(Value* other) const {
141 return definition() == other->definition(); 141 return definition() == other->definition();
142 } 142 }
143 143
144 144
145 static int OrderById(CidRange* const* a, CidRange* const* b) { 145 static int OrderById(CidRange* const* a, CidRange* const* b) {
146 // Negative if 'a' should sort before 'b'. 146 // Negative if 'a' should sort before 'b'.
147 ASSERT((*a)->cid_start == (*a)->cid_end); 147 ASSERT((*a)->IsSingleCid());
148 ASSERT((*b)->cid_start == (*b)->cid_end); 148 ASSERT((*b)->IsSingleCid());
149 return (*a)->cid_start - (*b)->cid_start; 149 return (*a)->cid_start - (*b)->cid_start;
150 } 150 }
151 151
152 152
153 static int OrderByFrequency(CidRange* const* a, CidRange* const* b) { 153 static int OrderByFrequency(CidRange* const* a, CidRange* const* b) {
154 const TargetInfo* target_info_a = static_cast<const TargetInfo*>(*a); 154 const TargetInfo* target_info_a = static_cast<const TargetInfo*>(*a);
155 const TargetInfo* target_info_b = static_cast<const TargetInfo*>(*b); 155 const TargetInfo* target_info_b = static_cast<const TargetInfo*>(*b);
156 // Negative if 'a' should sort before 'b'. 156 // Negative if 'a' should sort before 'b'.
157 return target_info_b->count - target_info_a->count; 157 return target_info_b->count - target_info_a->count;
158 } 158 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 intptr_t max = -1; 196 intptr_t max = -1;
197 for (intptr_t i = 0; i < cid_ranges_.length(); ++i) { 197 for (intptr_t i = 0; i < cid_ranges_.length(); ++i) {
198 max = Utils::Maximum(max, cid_ranges_[i]->cid_end); 198 max = Utils::Maximum(max, cid_ranges_[i]->cid_end);
199 } 199 }
200 return max; 200 return max;
201 } 201 }
202 202
203 203
204 bool Cids::HasClassId(intptr_t cid) const { 204 bool Cids::HasClassId(intptr_t cid) const {
205 for (int i = 0; i < length(); i++) { 205 for (int i = 0; i < length(); i++) {
206 if (cid_ranges_[i]->cid_start <= cid && cid <= cid_ranges_[i]->cid_end) { 206 if (cid_ranges_[i]->Contains(cid)) {
207 return true; 207 return true;
208 } 208 }
209 } 209 }
210 return false; 210 return false;
211 } 211 }
212 212
213 213
214 Cids* Cids::CreateMonomorphic(Zone* zone, intptr_t cid) { 214 Cids* Cids::CreateMonomorphic(Zone* zone, intptr_t cid) {
215 Cids* cids = new (zone) Cids(zone); 215 Cids* cids = new (zone) Cids(zone);
216 cids->Add(new (zone) CidRange(cid, cid)); 216 cids->Add(new (zone) CidRange(cid, cid));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 TargetInfo(id, id, &function, ic_data.GetCountAt(i))); 270 TargetInfo(id, id, &function, ic_data.GetCountAt(i)));
271 } else { 271 } else {
272 cid_ranges_.Add(new (zone) CidRange(id, id)); 272 cid_ranges_.Add(new (zone) CidRange(id, id));
273 } 273 }
274 } 274 }
275 } 275 }
276 276
277 277
278 bool Cids::IsMonomorphic() const { 278 bool Cids::IsMonomorphic() const {
279 if (length() != 1) return false; 279 if (length() != 1) return false;
280 return cid_ranges_[0]->cid_start == cid_ranges_[0]->cid_end; 280 return cid_ranges_[0]->IsSingleCid();
281 } 281 }
282 282
283 283
284 intptr_t Cids::MonomorphicReceiverCid() const { 284 intptr_t Cids::MonomorphicReceiverCid() const {
285 ASSERT(IsMonomorphic()); 285 ASSERT(IsMonomorphic());
286 return cid_ranges_[0]->cid_start; 286 return cid_ranges_[0]->cid_start;
287 } 287 }
288 288
289 289
290 CheckClassInstr::CheckClassInstr(Value* value, 290 CheckClassInstr::CheckClassInstr(Value* value,
291 intptr_t deopt_id, 291 intptr_t deopt_id,
292 const Cids& cids, 292 const Cids& cids,
293 TokenPosition token_pos) 293 TokenPosition token_pos)
294 : TemplateInstruction(deopt_id), 294 : TemplateInstruction(deopt_id),
295 cids_(cids), 295 cids_(cids),
296 licm_hoisted_(false), 296 licm_hoisted_(false),
297 is_bit_test_(IsCompactCidRange(cids)), 297 is_bit_test_(IsCompactCidRange(cids)),
298 token_pos_(token_pos) { 298 token_pos_(token_pos) {
299 // Expected useful check data. 299 // Expected useful check data.
300 const intptr_t number_of_checks = cids.length(); 300 const intptr_t number_of_checks = cids.length();
301 ASSERT(number_of_checks > 0); 301 ASSERT(number_of_checks > 0);
302 SetInputAt(0, value); 302 SetInputAt(0, value);
303 // Otherwise use CheckSmiInstr. 303 // Otherwise use CheckSmiInstr.
304 ASSERT(number_of_checks != 1 || cids[0].cid_start != cids[0].cid_end || 304 ASSERT(number_of_checks != 1 || !cids[0].IsSingleCid() ||
305 cids[0].cid_start != kSmiCid); 305 cids[0].cid_start != kSmiCid);
306 } 306 }
307 307
308 308
309 bool CheckClassInstr::AttributesEqual(Instruction* other) const { 309 bool CheckClassInstr::AttributesEqual(Instruction* other) const {
310 CheckClassInstr* other_check = other->AsCheckClass(); 310 CheckClassInstr* other_check = other->AsCheckClass();
311 ASSERT(other_check != NULL); 311 ASSERT(other_check != NULL);
312 return cids().Equals(other_check->cids()); 312 return cids().Equals(other_check->cids());
313 } 313 }
314 314
315 315
316 EffectSet CheckClassInstr::Dependencies() const { 316 EffectSet CheckClassInstr::Dependencies() const {
317 // Externalization of strings via the API can change the class-id. 317 // Externalization of strings via the API can change the class-id.
318 return cids_.ContainsExternalizableCids() ? EffectSet::Externalization() 318 return cids_.ContainsExternalizableCids() ? EffectSet::Externalization()
319 : EffectSet::None(); 319 : EffectSet::None();
320 } 320 }
321 321
322 322
323 EffectSet CheckClassIdInstr::Dependencies() const { 323 EffectSet CheckClassIdInstr::Dependencies() const {
324 // Externalization of strings via the API can change the class-id. 324 // Externalization of strings via the API can change the class-id.
325 return Field::IsExternalizableCid(cid_) ? EffectSet::Externalization() 325 for (intptr_t i = cids_.cid_start; i <= cids_.cid_end; i++) {
326 : EffectSet::None(); 326 if (Field::IsExternalizableCid(i)) return EffectSet::Externalization();
327 }
328 return EffectSet::None();
327 } 329 }
328 330
329 331
330 bool CheckClassInstr::IsDeoptIfNull() const { 332 bool CheckClassInstr::IsDeoptIfNull() const {
331 if (!cids().IsMonomorphic()) { 333 if (!cids().IsMonomorphic()) {
332 return false; 334 return false;
333 } 335 }
334 CompileType* in_type = value()->Type(); 336 CompileType* in_type = value()->Type();
335 const intptr_t cid = cids().MonomorphicReceiverCid(); 337 const intptr_t cid = cids().MonomorphicReceiverCid();
336 // Performance check: use CheckSmiInstr instead. 338 // Performance check: use CheckSmiInstr instead.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 bool CheckClassInstr::IsBitTest() const { 371 bool CheckClassInstr::IsBitTest() const {
370 return is_bit_test_; 372 return is_bit_test_;
371 } 373 }
372 374
373 375
374 intptr_t CheckClassInstr::ComputeCidMask() const { 376 intptr_t CheckClassInstr::ComputeCidMask() const {
375 ASSERT(IsBitTest()); 377 ASSERT(IsBitTest());
376 intptr_t min = cids_.ComputeLowestCid(); 378 intptr_t min = cids_.ComputeLowestCid();
377 intptr_t mask = 0; 379 intptr_t mask = 0;
378 for (intptr_t i = 0; i < cids_.length(); ++i) { 380 for (intptr_t i = 0; i < cids_.length(); ++i) {
379 intptr_t cid_start = cids_[i].cid_start;
380 intptr_t cid_end = cids_[i].cid_end;
381 intptr_t run; 381 intptr_t run;
382 uintptr_t range = 1ul + cid_end - cid_start; 382 uintptr_t range = 1ul + cids_[i].Extent();
383 if (range >= kBitsPerWord) { 383 if (range >= kBitsPerWord) {
384 run = -1; 384 run = -1;
385 } else { 385 } else {
386 run = (1 << range) - 1; 386 run = (1 << range) - 1;
387 } 387 }
388 mask |= run << (cid_start - min); 388 mask |= run << (cids_[i].cid_start - min);
389 } 389 }
390 return mask; 390 return mask;
391 } 391 }
392 392
393 393
394 bool LoadFieldInstr::IsUnboxedLoad() const { 394 bool LoadFieldInstr::IsUnboxedLoad() const {
395 return FLAG_unbox_numeric_fields && (field() != NULL) && 395 return FLAG_unbox_numeric_fields && (field() != NULL) &&
396 FlowGraphCompiler::IsUnboxedField(*field()); 396 FlowGraphCompiler::IsUnboxedField(*field());
397 } 397 }
398 398
(...skipping 2282 matching lines...) Expand 10 before | Expand all | Expand 10 after
2681 return this; 2681 return this;
2682 } 2682 }
2683 2683
2684 return cids().HasClassId(value_cid) ? NULL : this; 2684 return cids().HasClassId(value_cid) ? NULL : this;
2685 } 2685 }
2686 2686
2687 2687
2688 Instruction* CheckClassIdInstr::Canonicalize(FlowGraph* flow_graph) { 2688 Instruction* CheckClassIdInstr::Canonicalize(FlowGraph* flow_graph) {
2689 if (value()->BindsToConstant()) { 2689 if (value()->BindsToConstant()) {
2690 const Object& constant_value = value()->BoundConstant(); 2690 const Object& constant_value = value()->BoundConstant();
2691 if (constant_value.IsSmi() && Smi::Cast(constant_value).Value() == cid_) { 2691 if (constant_value.IsSmi() &&
2692 cids_.Contains(Smi::Cast(constant_value).Value())) {
2692 return NULL; 2693 return NULL;
2693 } 2694 }
2694 } 2695 }
2695 return this; 2696 return this;
2696 } 2697 }
2697 2698
2698 2699
2699 Definition* TestCidsInstr::Canonicalize(FlowGraph* flow_graph) { 2700 Definition* TestCidsInstr::Canonicalize(FlowGraph* flow_graph) {
2700 CompileType* in_type = left()->Type(); 2701 CompileType* in_type = left()->Type();
2701 intptr_t cid = in_type->ToCid(); 2702 intptr_t cid = in_type->ToCid();
(...skipping 1606 matching lines...) Expand 10 before | Expand all | Expand 10 after
4308 "native function '%s' (%" Pd " arguments) cannot be found", 4309 "native function '%s' (%" Pd " arguments) cannot be found",
4309 native_name().ToCString(), function().NumParameters()); 4310 native_name().ToCString(), function().NumParameters());
4310 } 4311 }
4311 set_is_auto_scope(auto_setup_scope); 4312 set_is_auto_scope(auto_setup_scope);
4312 set_native_c_function(native_function); 4313 set_native_c_function(native_function);
4313 } 4314 }
4314 4315
4315 #undef __ 4316 #undef __
4316 4317
4317 } // namespace dart 4318 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698