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

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

Issue 6903060: Version 3.3.2.... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 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/hydrogen-instructions.h ('k') | src/ia32/lithium-codegen-ia32.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 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 395
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
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
409 void HValue::PrintTypeTo(HType type, StringStream* stream) { 405 void HValue::PrintTypeTo(HType type, StringStream* stream) {
(...skipping 10 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 if (removed == NULL) {
434 new_value->use_list_ =
435 new HUseListNode(this, index, new_value->use_list_);
436 } else {
437 removed->set_tail(new_value->use_list_);
438 new_value->use_list_ = removed;
439 }
433 } 440 }
434 } 441 }
435 442
436 443
437 void HValue::AddNewRange(Range* r) { 444 void HValue::AddNewRange(Range* r) {
438 if (!HasRange()) ComputeInitialRange(); 445 if (!HasRange()) ComputeInitialRange();
439 if (!HasRange()) range_ = new Range(); 446 if (!HasRange()) range_ = new Range();
440 ASSERT(HasRange()); 447 ASSERT(HasRange());
441 r->StackUpon(range_); 448 r->StackUpon(range_);
442 range_ = r; 449 range_ = r;
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 926
920 void HPhi::PrintTo(StringStream* stream) { 927 void HPhi::PrintTo(StringStream* stream) {
921 stream->Add("["); 928 stream->Add("[");
922 for (int i = 0; i < OperandCount(); ++i) { 929 for (int i = 0; i < OperandCount(); ++i) {
923 HValue* value = OperandAt(i); 930 HValue* value = OperandAt(i);
924 stream->Add(" "); 931 stream->Add(" ");
925 value->PrintNameTo(stream); 932 value->PrintNameTo(stream);
926 stream->Add(" "); 933 stream->Add(" ");
927 } 934 }
928 stream->Add(" uses%d_%di_%dd_%dt]", 935 stream->Add(" uses%d_%di_%dd_%dt]",
929 uses()->length(), 936 UseCount(),
930 int32_non_phi_uses() + int32_indirect_uses(), 937 int32_non_phi_uses() + int32_indirect_uses(),
931 double_non_phi_uses() + double_indirect_uses(), 938 double_non_phi_uses() + double_indirect_uses(),
932 tagged_non_phi_uses() + tagged_indirect_uses()); 939 tagged_non_phi_uses() + tagged_indirect_uses());
933 } 940 }
934 941
935 942
936 void HPhi::AddInput(HValue* value) { 943 void HPhi::AddInput(HValue* value) {
937 inputs_.Add(NULL); 944 inputs_.Add(NULL);
938 SetOperandAt(OperandCount() - 1, value); 945 SetOperandAt(OperandCount() - 1, value);
939 // Mark phis that may have 'arguments' directly or indirectly as an operand. 946 // Mark phis that may have 'arguments' directly or indirectly as an operand.
940 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) { 947 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) {
941 SetFlag(kIsArguments); 948 SetFlag(kIsArguments);
942 } 949 }
943 } 950 }
944 951
945 952
946 bool HPhi::HasRealUses() { 953 bool HPhi::HasRealUses() {
947 for (int i = 0; i < uses()->length(); i++) { 954 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
948 if (!uses()->at(i)->IsPhi()) return true; 955 if (!it.value()->IsPhi()) return true;
949 } 956 }
950 return false; 957 return false;
951 } 958 }
952 959
953 960
954 HValue* HPhi::GetRedundantReplacement() { 961 HValue* HPhi::GetRedundantReplacement() {
955 HValue* candidate = NULL; 962 HValue* candidate = NULL;
956 int count = OperandCount(); 963 int count = OperandCount();
957 int position = 0; 964 int position = 0;
958 while (position < count && candidate == NULL) { 965 while (position < count && candidate == NULL) {
(...skipping 12 matching lines...) Expand all
971 void HPhi::DeleteFromGraph() { 978 void HPhi::DeleteFromGraph() {
972 ASSERT(block() != NULL); 979 ASSERT(block() != NULL);
973 block()->RemovePhi(this); 980 block()->RemovePhi(this);
974 ASSERT(block() == NULL); 981 ASSERT(block() == NULL);
975 } 982 }
976 983
977 984
978 void HPhi::InitRealUses(int phi_id) { 985 void HPhi::InitRealUses(int phi_id) {
979 // Initialize real uses. 986 // Initialize real uses.
980 phi_id_ = phi_id; 987 phi_id_ = phi_id;
981 for (int j = 0; j < uses()->length(); j++) { 988 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
982 HValue* use = uses()->at(j); 989 HValue* value = it.value();
983 if (!use->IsPhi()) { 990 if (!value->IsPhi()) {
984 int index = use->LookupOperandIndex(0, this); 991 Representation rep = value->RequiredInputRepresentation(it.index());
985 Representation req_rep = use->RequiredInputRepresentation(index); 992 ++non_phi_uses_[rep.kind()];
986 non_phi_uses_[req_rep.kind()]++;
987 } 993 }
988 } 994 }
989 } 995 }
990 996
991 997
992 void HPhi::AddNonPhiUsesFrom(HPhi* other) { 998 void HPhi::AddNonPhiUsesFrom(HPhi* other) {
993 for (int i = 0; i < Representation::kNumRepresentations; i++) { 999 for (int i = 0; i < Representation::kNumRepresentations; i++) {
994 indirect_uses_[i] += other->non_phi_uses_[i]; 1000 indirect_uses_[i] += other->non_phi_uses_[i];
995 } 1001 }
996 } 1002 }
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 break; 1280 break;
1275 case kExternalIntArray: 1281 case kExternalIntArray:
1276 stream->Add("int"); 1282 stream->Add("int");
1277 break; 1283 break;
1278 case kExternalUnsignedIntArray: 1284 case kExternalUnsignedIntArray:
1279 stream->Add("u_int"); 1285 stream->Add("u_int");
1280 break; 1286 break;
1281 case kExternalFloatArray: 1287 case kExternalFloatArray:
1282 stream->Add("float"); 1288 stream->Add("float");
1283 break; 1289 break;
1290 case kExternalDoubleArray:
1291 stream->Add("double");
1292 break;
1284 case kExternalPixelArray: 1293 case kExternalPixelArray:
1285 stream->Add("pixel"); 1294 stream->Add("pixel");
1286 break; 1295 break;
1287 } 1296 }
1288 stream->Add("["); 1297 stream->Add("[");
1289 key()->PrintNameTo(stream); 1298 key()->PrintNameTo(stream);
1290 stream->Add("]"); 1299 stream->Add("]");
1291 } 1300 }
1292 1301
1293 1302
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 break; 1360 break;
1352 case kExternalIntArray: 1361 case kExternalIntArray:
1353 stream->Add("int"); 1362 stream->Add("int");
1354 break; 1363 break;
1355 case kExternalUnsignedIntArray: 1364 case kExternalUnsignedIntArray:
1356 stream->Add("u_int"); 1365 stream->Add("u_int");
1357 break; 1366 break;
1358 case kExternalFloatArray: 1367 case kExternalFloatArray:
1359 stream->Add("float"); 1368 stream->Add("float");
1360 break; 1369 break;
1370 case kExternalDoubleArray:
1371 stream->Add("double");
1372 break;
1361 case kExternalPixelArray: 1373 case kExternalPixelArray:
1362 stream->Add("pixel"); 1374 stream->Add("pixel");
1363 break; 1375 break;
1364 } 1376 }
1365 stream->Add("["); 1377 stream->Add("[");
1366 key()->PrintNameTo(stream); 1378 key()->PrintNameTo(stream);
1367 stream->Add("] = "); 1379 stream->Add("] = ");
1368 value()->PrintNameTo(stream); 1380 value()->PrintNameTo(stream);
1369 } 1381 }
1370 1382
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 visited->Add(id()); 1604 visited->Add(id());
1593 // Propagate to the left argument. If the left argument cannot be -0, then 1605 // Propagate to the left argument. If the left argument cannot be -0, then
1594 // the result of the sub operation cannot be either. 1606 // the result of the sub operation cannot be either.
1595 if (range() == NULL || range()->CanBeMinusZero()) { 1607 if (range() == NULL || range()->CanBeMinusZero()) {
1596 return left(); 1608 return left();
1597 } 1609 }
1598 return NULL; 1610 return NULL;
1599 } 1611 }
1600 1612
1601 1613
1614 void HIn::PrintDataTo(StringStream* stream) {
1615 key()->PrintNameTo(stream);
1616 stream->Add(" ");
1617 object()->PrintNameTo(stream);
1618 }
1619
1620
1602 // Node-specific verification code is only included in debug mode. 1621 // Node-specific verification code is only included in debug mode.
1603 #ifdef DEBUG 1622 #ifdef DEBUG
1604 1623
1605 void HPhi::Verify() { 1624 void HPhi::Verify() {
1606 ASSERT(OperandCount() == block()->predecessors()->length()); 1625 ASSERT(OperandCount() == block()->predecessors()->length());
1607 for (int i = 0; i < OperandCount(); ++i) { 1626 for (int i = 0; i < OperandCount(); ++i) {
1608 HValue* value = OperandAt(i); 1627 HValue* value = OperandAt(i);
1609 HBasicBlock* defining_block = value->block(); 1628 HBasicBlock* defining_block = value->block();
1610 HBasicBlock* predecessor_block = block()->predecessors()->at(i); 1629 HBasicBlock* predecessor_block = block()->predecessors()->at(i);
1611 ASSERT(defining_block == predecessor_block || 1630 ASSERT(defining_block == predecessor_block ||
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 1676
1658 1677
1659 void HCheckPrototypeMaps::Verify() { 1678 void HCheckPrototypeMaps::Verify() {
1660 HInstruction::Verify(); 1679 HInstruction::Verify();
1661 ASSERT(HasNoUses()); 1680 ASSERT(HasNoUses());
1662 } 1681 }
1663 1682
1664 #endif 1683 #endif
1665 1684
1666 } } // namespace v8::internal 1685 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698