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

Side by Side Diff: src/hydrogen-instructions.cc

Issue 6881044: Change the Hydrogen representation of uses. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 result = HType::Boolean(); 257 result = HType::Boolean();
258 } else if (value->IsJSObject()) { 258 } else if (value->IsJSObject()) {
259 result = HType::JSObject(); 259 result = HType::JSObject();
260 } else if (value->IsJSArray()) { 260 } else if (value->IsJSArray()) {
261 result = HType::JSArray(); 261 result = HType::JSArray();
262 } 262 }
263 return result; 263 return result;
264 } 264 }
265 265
266 266
267 int HValue::LookupOperandIndex(int occurrence_index, HValue* op) {
268 for (int i = 0; i < OperandCount(); ++i) {
269 if (OperandAt(i) == op) {
270 if (occurrence_index == 0) return i;
271 --occurrence_index;
272 }
273 }
274 return -1;
275 }
276
277
278 bool HValue::IsDefinedAfter(HBasicBlock* other) const { 267 bool HValue::IsDefinedAfter(HBasicBlock* other) const {
279 return block()->block_id() > other->block_id(); 268 return block()->block_id() > other->block_id();
280 } 269 }
281 270
282 271
283 bool HValue::UsesMultipleTimes(HValue* op) { 272 HUseIterator::HUseIterator(HUseListNode* head) : next_(head) {
284 bool seen = false; 273 Advance();
285 for (int i = 0; i < OperandCount(); ++i) {
286 if (OperandAt(i) == op) {
287 if (seen) return true;
288 seen = true;
289 }
290 }
291 return false;
292 } 274 }
293 275
294 276
277 void HUseIterator::Advance() {
278 current_ = next_;
279 if (current_ != NULL) {
280 next_ = current_->tail();
281 value_ = current_->value();
282 index_ = current_->index();
283 }
284 }
285
286
287 int HValue::UseCount() const {
288 int count = 0;
289 for (HUseIterator it(uses()); !it.Done(); it.Advance()) ++count;
290 return count;
291 }
292
293
294 HUseListNode* HValue::RemoveUse(HValue* value, int index) {
295 HUseListNode* previous = NULL;
296 HUseListNode* current = use_list_;
297 while (current != NULL) {
298 if (current->value() == value && current->index() == index) {
299 if (previous == NULL) {
300 use_list_ = current->tail();
301 } else {
302 previous->set_tail(current->tail());
303 }
304 break;
305 }
306
307 previous = current;
308 current = current->tail();
309 }
310
311 #ifdef DEBUG
312 // Do not reuse use list nodes in debug mode, zap them.
313 if (current != NULL) {
314 HUseListNode* temp =
315 new HUseListNode(current->value(), current->index(), NULL);
316 current->Zap();
317 current = temp;
318 }
319 #endif
320 return current;
321 }
322
323
295 bool HValue::Equals(HValue* other) { 324 bool HValue::Equals(HValue* other) {
296 if (other->opcode() != opcode()) return false; 325 if (other->opcode() != opcode()) return false;
297 if (!other->representation().Equals(representation())) return false; 326 if (!other->representation().Equals(representation())) return false;
298 if (!other->type_.Equals(type_)) return false; 327 if (!other->type_.Equals(type_)) return false;
299 if (other->flags() != flags()) return false; 328 if (other->flags() != flags()) return false;
300 if (OperandCount() != other->OperandCount()) return false; 329 if (OperandCount() != other->OperandCount()) return false;
301 for (int i = 0; i < OperandCount(); ++i) { 330 for (int i = 0; i < OperandCount(); ++i) {
302 if (OperandAt(i)->id() != other->OperandAt(i)->id()) return false; 331 if (OperandAt(i)->id() != other->OperandAt(i)->id()) return false;
303 } 332 }
304 bool result = DataEquals(other); 333 bool result = DataEquals(other);
(...skipping 23 matching lines...) Expand all
328 } 357 }
329 358
330 359
331 void HValue::SetOperandAt(int index, HValue* value) { 360 void HValue::SetOperandAt(int index, HValue* value) {
332 ASSERT(value == NULL || !value->representation().IsNone()); 361 ASSERT(value == NULL || !value->representation().IsNone());
333 RegisterUse(index, value); 362 RegisterUse(index, value);
334 InternalSetOperandAt(index, value); 363 InternalSetOperandAt(index, value);
335 } 364 }
336 365
337 366
338 void HValue::ReplaceAndDelete(HValue* other) { 367 void HValue::DeleteAndReplaceWith(HValue* other) {
339 if (other != NULL) ReplaceValue(other); 368 // We replace all uses first, so Delete can assert that there are none.
340 Delete(); 369 if (other != NULL) ReplaceAllUsesWith(other);
370 ASSERT(HasNoUses());
371 ClearOperands();
372 DeleteFromGraph();
341 } 373 }
342 374
343 375
344 void HValue::ReplaceValue(HValue* other) { 376 void HValue::ReplaceAllUsesWith(HValue* other) {
345 for (int i = 0; i < uses_.length(); ++i) { 377 while (use_list_ != NULL) {
346 HValue* use = uses_[i]; 378 HUseListNode* list_node = use_list_;
347 ASSERT(!use->block()->IsStartBlock()); 379 HValue* value = list_node->value();
348 InternalReplaceAtUse(use, other); 380 ASSERT(!value->block()->IsStartBlock());
349 other->uses_.Add(use); 381 value->InternalSetOperandAt(list_node->index(), other);
382 use_list_ = list_node->tail();
383 list_node->set_tail(other->use_list_);
384 other->use_list_ = list_node;
350 } 385 }
351 uses_.Rewind(0);
352 } 386 }
353 387
354 388
355 void HValue::ClearOperands() { 389 void HValue::ClearOperands() {
356 for (int i = 0; i < OperandCount(); ++i) { 390 for (int i = 0; i < OperandCount(); ++i) {
357 SetOperandAt(i, NULL); 391 SetOperandAt(i, NULL);
358 } 392 }
359 } 393 }
360 394
361
362 void HValue::Delete() {
363 ASSERT(HasNoUses());
364 ClearOperands();
365 DeleteFromGraph();
366 }
367
368
369 void HValue::ReplaceAtUse(HValue* use, HValue* other) {
370 for (int i = 0; i < use->OperandCount(); ++i) {
371 if (use->OperandAt(i) == this) {
372 use->SetOperandAt(i, other);
373 }
374 }
375 }
376
377
378 void HValue::ReplaceFirstAtUse(HValue* use, HValue* other, Representation r) {
379 for (int i = 0; i < use->OperandCount(); ++i) {
380 if (use->RequiredInputRepresentation(i).Equals(r) &&
381 use->OperandAt(i) == this) {
382 use->SetOperandAt(i, other);
383 return;
384 }
385 }
386 }
387
388
389 void HValue::InternalReplaceAtUse(HValue* use, HValue* other) {
390 for (int i = 0; i < use->OperandCount(); ++i) {
391 if (use->OperandAt(i) == this) {
392 // Call internal method that does not update use lists. The caller is
393 // responsible for doing so.
394 use->InternalSetOperandAt(i, other);
395 }
396 }
397 }
398
399 395
400 void HValue::SetBlock(HBasicBlock* block) { 396 void HValue::SetBlock(HBasicBlock* block) {
401 ASSERT(block_ == NULL || block == NULL); 397 ASSERT(block_ == NULL || block == NULL);
402 block_ = block; 398 block_ = block;
403 if (id_ == kNoNumber && block != NULL) { 399 if (id_ == kNoNumber && block != NULL) {
404 id_ = block->graph()->GetNextValueID(this); 400 id_ = block->graph()->GetNextValueID(this);
405 } 401 }
406 } 402 }
407 403
408 404
(...skipping 11 matching lines...) Expand all
420 HType type = CalculateInferredType(); 416 HType type = CalculateInferredType();
421 bool result = (!type.Equals(type_)); 417 bool result = (!type.Equals(type_));
422 type_ = type; 418 type_ = type;
423 return result; 419 return result;
424 } 420 }
425 421
426 422
427 void HValue::RegisterUse(int index, HValue* new_value) { 423 void HValue::RegisterUse(int index, HValue* new_value) {
428 HValue* old_value = OperandAt(index); 424 HValue* old_value = OperandAt(index);
429 if (old_value == new_value) return; 425 if (old_value == new_value) return;
430 if (old_value != NULL) old_value->uses_.RemoveElement(this); 426
427 HUseListNode* removed = NULL;
428 if (old_value != NULL) {
429 removed = old_value->RemoveUse(this, index);
430 }
431
431 if (new_value != NULL) { 432 if (new_value != NULL) {
432 new_value->uses_.Add(this); 433 #ifdef DEBUG
434 // Never reuse list nodes in debug builds.
435 removed = NULL;
436 #endif
437 if (removed == NULL) {
438 new_value->use_list_ = new HUseListNode(this, index, new_value->use_list_) ;
439 } else {
440 removed->set_tail(new_value->use_list_);
441 new_value->use_list_ = removed;
442 }
433 } 443 }
434 } 444 }
435 445
436 446
437 void HValue::AddNewRange(Range* r) { 447 void HValue::AddNewRange(Range* r) {
438 if (!HasRange()) ComputeInitialRange(); 448 if (!HasRange()) ComputeInitialRange();
439 if (!HasRange()) range_ = new Range(); 449 if (!HasRange()) range_ = new Range();
440 ASSERT(HasRange()); 450 ASSERT(HasRange());
441 r->StackUpon(range_); 451 r->StackUpon(range_);
442 range_ = r; 452 range_ = r;
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 929
920 void HPhi::PrintTo(StringStream* stream) { 930 void HPhi::PrintTo(StringStream* stream) {
921 stream->Add("["); 931 stream->Add("[");
922 for (int i = 0; i < OperandCount(); ++i) { 932 for (int i = 0; i < OperandCount(); ++i) {
923 HValue* value = OperandAt(i); 933 HValue* value = OperandAt(i);
924 stream->Add(" "); 934 stream->Add(" ");
925 value->PrintNameTo(stream); 935 value->PrintNameTo(stream);
926 stream->Add(" "); 936 stream->Add(" ");
927 } 937 }
928 stream->Add(" uses%d_%di_%dd_%dt]", 938 stream->Add(" uses%d_%di_%dd_%dt]",
929 uses()->length(), 939 UseCount(),
930 int32_non_phi_uses() + int32_indirect_uses(), 940 int32_non_phi_uses() + int32_indirect_uses(),
931 double_non_phi_uses() + double_indirect_uses(), 941 double_non_phi_uses() + double_indirect_uses(),
932 tagged_non_phi_uses() + tagged_indirect_uses()); 942 tagged_non_phi_uses() + tagged_indirect_uses());
933 } 943 }
934 944
935 945
936 void HPhi::AddInput(HValue* value) { 946 void HPhi::AddInput(HValue* value) {
937 inputs_.Add(NULL); 947 inputs_.Add(NULL);
938 SetOperandAt(OperandCount() - 1, value); 948 SetOperandAt(OperandCount() - 1, value);
939 // Mark phis that may have 'arguments' directly or indirectly as an operand. 949 // Mark phis that may have 'arguments' directly or indirectly as an operand.
940 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) { 950 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) {
941 SetFlag(kIsArguments); 951 SetFlag(kIsArguments);
942 } 952 }
943 } 953 }
944 954
945 955
946 bool HPhi::HasRealUses() { 956 bool HPhi::HasRealUses() {
947 for (int i = 0; i < uses()->length(); i++) { 957 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
948 if (!uses()->at(i)->IsPhi()) return true; 958 if (!it.value()->IsPhi()) return true;
949 } 959 }
950 return false; 960 return false;
951 } 961 }
952 962
953 963
954 HValue* HPhi::GetRedundantReplacement() { 964 HValue* HPhi::GetRedundantReplacement() {
955 HValue* candidate = NULL; 965 HValue* candidate = NULL;
956 int count = OperandCount(); 966 int count = OperandCount();
957 int position = 0; 967 int position = 0;
958 while (position < count && candidate == NULL) { 968 while (position < count && candidate == NULL) {
(...skipping 12 matching lines...) Expand all
971 void HPhi::DeleteFromGraph() { 981 void HPhi::DeleteFromGraph() {
972 ASSERT(block() != NULL); 982 ASSERT(block() != NULL);
973 block()->RemovePhi(this); 983 block()->RemovePhi(this);
974 ASSERT(block() == NULL); 984 ASSERT(block() == NULL);
975 } 985 }
976 986
977 987
978 void HPhi::InitRealUses(int phi_id) { 988 void HPhi::InitRealUses(int phi_id) {
979 // Initialize real uses. 989 // Initialize real uses.
980 phi_id_ = phi_id; 990 phi_id_ = phi_id;
981 for (int j = 0; j < uses()->length(); j++) { 991 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
982 HValue* use = uses()->at(j); 992 HValue* value = it.value();
983 if (!use->IsPhi()) { 993 if (!value->IsPhi()) {
984 int index = use->LookupOperandIndex(0, this); 994 Representation rep = value->RequiredInputRepresentation(it.index());
985 Representation req_rep = use->RequiredInputRepresentation(index); 995 ++non_phi_uses_[rep.kind()];
986 non_phi_uses_[req_rep.kind()]++;
987 } 996 }
988 } 997 }
989 } 998 }
990 999
991 1000
992 void HPhi::AddNonPhiUsesFrom(HPhi* other) { 1001 void HPhi::AddNonPhiUsesFrom(HPhi* other) {
993 for (int i = 0; i < Representation::kNumRepresentations; i++) { 1002 for (int i = 0; i < Representation::kNumRepresentations; i++) {
994 indirect_uses_[i] += other->non_phi_uses_[i]; 1003 indirect_uses_[i] += other->non_phi_uses_[i];
995 } 1004 }
996 } 1005 }
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 1666
1658 1667
1659 void HCheckPrototypeMaps::Verify() { 1668 void HCheckPrototypeMaps::Verify() {
1660 HInstruction::Verify(); 1669 HInstruction::Verify();
1661 ASSERT(HasNoUses()); 1670 ASSERT(HasNoUses());
1662 } 1671 }
1663 1672
1664 #endif 1673 #endif
1665 1674
1666 } } // namespace v8::internal 1675 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698