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

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

Issue 141363005: A64: Synchronize with r15204. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 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/assembler-ia32.h » ('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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 } 79 }
80 } 80 }
81 81
82 82
83 void HValue::InferRepresentation(HInferRepresentation* h_infer) { 83 void HValue::InferRepresentation(HInferRepresentation* h_infer) {
84 ASSERT(CheckFlag(kFlexibleRepresentation)); 84 ASSERT(CheckFlag(kFlexibleRepresentation));
85 Representation new_rep = RepresentationFromInputs(); 85 Representation new_rep = RepresentationFromInputs();
86 UpdateRepresentation(new_rep, h_infer, "inputs"); 86 UpdateRepresentation(new_rep, h_infer, "inputs");
87 new_rep = RepresentationFromUses(); 87 new_rep = RepresentationFromUses();
88 UpdateRepresentation(new_rep, h_infer, "uses"); 88 UpdateRepresentation(new_rep, h_infer, "uses");
89 new_rep = RepresentationFromUseRequirements();
90 if (new_rep.fits_into(Representation::Integer32())) {
91 UpdateRepresentation(new_rep, h_infer, "use requirements");
92 }
89 } 93 }
90 94
91 95
92 Representation HValue::RepresentationFromUses() { 96 Representation HValue::RepresentationFromUses() {
93 if (HasNoUses()) return Representation::None(); 97 if (HasNoUses()) return Representation::None();
94 98
95 // Array of use counts for each representation. 99 // Array of use counts for each representation.
96 int use_count[Representation::kNumRepresentations] = { 0 }; 100 int use_count[Representation::kNumRepresentations] = { 0 };
97 101
98 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 102 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 stream->Add(" + %d) >> %d)", offset(), scale()); 1146 stream->Add(" + %d) >> %d)", offset(), scale());
1143 } 1147 }
1144 if (skip_check()) { 1148 if (skip_check()) {
1145 stream->Add(" [DISABLED]"); 1149 stream->Add(" [DISABLED]");
1146 } 1150 }
1147 } 1151 }
1148 1152
1149 1153
1150 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { 1154 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) {
1151 ASSERT(CheckFlag(kFlexibleRepresentation)); 1155 ASSERT(CheckFlag(kFlexibleRepresentation));
1152 Representation r;
1153 HValue* actual_index = index()->ActualValue(); 1156 HValue* actual_index = index()->ActualValue();
1154 HValue* actual_length = length()->ActualValue(); 1157 HValue* actual_length = length()->ActualValue();
1155 Representation index_rep = actual_index->representation(); 1158 Representation index_rep = actual_index->representation();
1156 if (!actual_length->representation().IsSmiOrTagged()) { 1159 Representation length_rep = actual_length->representation();
1157 r = Representation::Integer32(); 1160 if (index_rep.IsTagged()) index_rep = Representation::Smi();
1158 } else if ((index_rep.IsTagged() && actual_index->type().IsSmi()) || 1161 if (length_rep.IsTagged()) length_rep = Representation::Smi();
1159 index_rep.IsSmi()) { 1162 Representation r = index_rep.generalize(length_rep);
1160 // If the index is smi, allow the length to be smi, since it is usually 1163 if (r.is_more_general_than(Representation::Integer32())) {
1161 // already smi from loading it out of the length field of a JSArray. This
1162 // allows for direct comparison without untagging.
1163 r = Representation::Smi();
1164 } else {
1165 r = Representation::Integer32(); 1164 r = Representation::Integer32();
1166 } 1165 }
1167 UpdateRepresentation(r, h_infer, "boundscheck"); 1166 UpdateRepresentation(r, h_infer, "boundscheck");
1168 } 1167 }
1169 1168
1170 1169
1171 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal( 1170 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal(
1172 NumericRelation relation, 1171 NumericRelation relation,
1173 HValue* related_value, 1172 HValue* related_value,
1174 int offset, 1173 int offset,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 ToBooleanStub::UNDEFINED | 1281 ToBooleanStub::UNDEFINED |
1283 ToBooleanStub::NULL_TYPE | 1282 ToBooleanStub::NULL_TYPE |
1284 ToBooleanStub::SPEC_OBJECT | 1283 ToBooleanStub::SPEC_OBJECT |
1285 ToBooleanStub::STRING | 1284 ToBooleanStub::STRING |
1286 ToBooleanStub::SYMBOL); 1285 ToBooleanStub::SYMBOL);
1287 if (expected_input_types_.ContainsAnyOf(tagged_types)) { 1286 if (expected_input_types_.ContainsAnyOf(tagged_types)) {
1288 return Representation::Tagged(); 1287 return Representation::Tagged();
1289 } else if (expected_input_types_.Contains(ToBooleanStub::HEAP_NUMBER)) { 1288 } else if (expected_input_types_.Contains(ToBooleanStub::HEAP_NUMBER)) {
1290 return Representation::Double(); 1289 return Representation::Double();
1291 } else if (expected_input_types_.Contains(ToBooleanStub::SMI)) { 1290 } else if (expected_input_types_.Contains(ToBooleanStub::SMI)) {
1292 return Representation::Integer32(); 1291 return Representation::Smi();
1293 } else { 1292 } else {
1294 return Representation::None(); 1293 return Representation::None();
1295 } 1294 }
1296 } 1295 }
1297 1296
1298 1297
1299 void HCompareMap::PrintDataTo(StringStream* stream) { 1298 void HCompareMap::PrintDataTo(StringStream* stream) {
1300 value()->PrintNameTo(stream); 1299 value()->PrintNameTo(stream);
1301 stream->Add(" (%p)", *map()); 1300 stream->Add(" (%p)", *map());
1302 HControlInstruction::PrintDataTo(stream); 1301 HControlInstruction::PrintDataTo(stream);
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 void HChange::PrintDataTo(StringStream* stream) { 1505 void HChange::PrintDataTo(StringStream* stream) {
1507 HUnaryOperation::PrintDataTo(stream); 1506 HUnaryOperation::PrintDataTo(stream);
1508 stream->Add(" %s to %s", from().Mnemonic(), to().Mnemonic()); 1507 stream->Add(" %s to %s", from().Mnemonic(), to().Mnemonic());
1509 1508
1510 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); 1509 if (CanTruncateToInt32()) stream->Add(" truncating-int32");
1511 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); 1510 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
1512 if (CheckFlag(kAllowUndefinedAsNaN)) stream->Add(" allow-undefined-as-nan"); 1511 if (CheckFlag(kAllowUndefinedAsNaN)) stream->Add(" allow-undefined-as-nan");
1513 } 1512 }
1514 1513
1515 1514
1515 static HValue* SimplifiedDividendForMathFloorOfDiv(HValue* dividend) {
1516 // A value with an integer representation does not need to be transformed.
1517 if (dividend->representation().IsInteger32()) {
1518 return dividend;
1519 }
1520 // A change from an integer32 can be replaced by the integer32 value.
1521 if (dividend->IsChange() &&
1522 HChange::cast(dividend)->from().IsInteger32()) {
1523 return HChange::cast(dividend)->value();
1524 }
1525 return NULL;
1526 }
1527
1528
1516 HValue* HUnaryMathOperation::Canonicalize() { 1529 HValue* HUnaryMathOperation::Canonicalize() {
1517 if (op() == kMathFloor) { 1530 if (op() == kMathFloor) {
1531 HValue* val = value();
1532 if (val->IsChange()) val = HChange::cast(val)->value();
1533
1518 // If the input is integer32 then we replace the floor instruction 1534 // If the input is integer32 then we replace the floor instruction
1519 // with its input. This happens before the representation changes are 1535 // with its input.
1520 // introduced. 1536 if (val->representation().IsInteger32()) return val;
1521
1522 // TODO(2205): The above comment is lying. All of this happens
1523 // *after* representation changes are introduced. We should check
1524 // for value->IsChange() and react accordingly if yes.
1525
1526 if (value()->representation().IsInteger32()) return value();
1527 1537
1528 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \ 1538 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \
1529 defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_A64) 1539 defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_A64)
1530 if (value()->IsDiv() && (value()->UseCount() == 1)) { 1540 if (value()->IsDiv() && (value()->UseCount() == 1)) {
1531 // TODO(2038): Implement this optimization for non ARM architectures. 1541 // TODO(2038): Implement this optimization for non ARM architectures.
1532 HDiv* hdiv = HDiv::cast(value()); 1542 HDiv* hdiv = HDiv::cast(value());
1533 HValue* left = hdiv->left(); 1543 HValue* left = hdiv->left();
1534 HValue* right = hdiv->right(); 1544 HValue* right = hdiv->right();
1535 // Try to simplify left and right values of the division. 1545 // Try to simplify left and right values of the division.
1536 HValue* new_left = 1546 HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left);
1537 LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(left); 1547 if (new_left == NULL &&
1548 hdiv->observed_input_representation(1).IsSmiOrInteger32()) {
1549 new_left = new(block()->zone())
1550 HChange(left, Representation::Integer32(), false, false);
1551 HChange::cast(new_left)->InsertBefore(this);
1552 }
1538 HValue* new_right = 1553 HValue* new_right =
1539 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right); 1554 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right);
1555 if (new_right == NULL &&
1556 #ifdef V8_TARGET_ARCH_ARM
1557 CpuFeatures::IsSupported(SUDIV) &&
1558 #endif
1559 hdiv->observed_input_representation(2).IsSmiOrInteger32()) {
1560 new_right = new(block()->zone())
1561 HChange(right, Representation::Integer32(), false, false);
1562 HChange::cast(new_right)->InsertBefore(this);
1563 }
1540 1564
1541 // Return if left or right are not optimizable. 1565 // Return if left or right are not optimizable.
1542 if ((new_left == NULL) || (new_right == NULL)) return this; 1566 if ((new_left == NULL) || (new_right == NULL)) return this;
1543 1567
1544 // Insert the new values in the graph. 1568 // Insert the new values in the graph.
1545 if (new_left->IsInstruction() && 1569 if (new_left->IsInstruction() &&
1546 !HInstruction::cast(new_left)->IsLinked()) { 1570 !HInstruction::cast(new_left)->IsLinked()) {
1547 HInstruction::cast(new_left)->InsertBefore(this); 1571 HInstruction::cast(new_left)->InsertBefore(this);
1548 } 1572 }
1549 if (new_right->IsInstruction() && 1573 if (new_right->IsInstruction() &&
1550 !HInstruction::cast(new_right)->IsLinked()) { 1574 !HInstruction::cast(new_right)->IsLinked()) {
1551 HInstruction::cast(new_right)->InsertBefore(this); 1575 HInstruction::cast(new_right)->InsertBefore(this);
1552 } 1576 }
1553 HMathFloorOfDiv* instr = new(block()->zone()) HMathFloorOfDiv(context(), 1577 HMathFloorOfDiv* instr = new(block()->zone())
1554 new_left, 1578 HMathFloorOfDiv(context(), new_left, new_right);
1555 new_right);
1556 // Replace this HMathFloor instruction by the new HMathFloorOfDiv. 1579 // Replace this HMathFloor instruction by the new HMathFloorOfDiv.
1557 instr->InsertBefore(this); 1580 instr->InsertBefore(this);
1558 ReplaceAllUsesWith(instr); 1581 ReplaceAllUsesWith(instr);
1559 Kill(); 1582 Kill();
1560 // We know the division had no other uses than this HMathFloor. Delete it. 1583 // We know the division had no other uses than this HMathFloor. Delete it.
1561 // Also delete the arguments of the division if they are not used any 1584 // Dead code elimination will deal with |left| and |right| if
1562 // more. 1585 // appropriate.
1563 hdiv->DeleteAndReplaceWith(NULL); 1586 hdiv->DeleteAndReplaceWith(NULL);
1564 ASSERT(left->IsChange() || left->IsConstant());
1565 ASSERT(right->IsChange() || right->IsConstant());
1566 if (left->HasNoUses()) left->DeleteAndReplaceWith(NULL);
1567 if (right->HasNoUses()) right->DeleteAndReplaceWith(NULL);
1568 1587
1569 // Return NULL to remove this instruction from the graph. 1588 // Return NULL to remove this instruction from the graph.
1570 return NULL; 1589 return NULL;
1571 } 1590 }
1572 #endif // V8_TARGET_ARCH_ARM 1591 #endif
1573 } 1592 }
1574 return this; 1593 return this;
1575 } 1594 }
1576 1595
1577 1596
1578 HValue* HCheckInstanceType::Canonicalize() { 1597 HValue* HCheckInstanceType::Canonicalize() {
1579 if (check_ == IS_STRING && 1598 if (check_ == IS_STRING &&
1580 !value()->type().IsUninitialized() && 1599 !value()->type().IsUninitialized() &&
1581 value()->type().IsString()) { 1600 value()->type().IsString()) {
1582 return NULL; 1601 return NULL;
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
2299 2318
2300 void HBinaryOperation::InferRepresentation(HInferRepresentation* h_infer) { 2319 void HBinaryOperation::InferRepresentation(HInferRepresentation* h_infer) {
2301 ASSERT(CheckFlag(kFlexibleRepresentation)); 2320 ASSERT(CheckFlag(kFlexibleRepresentation));
2302 Representation new_rep = RepresentationFromInputs(); 2321 Representation new_rep = RepresentationFromInputs();
2303 UpdateRepresentation(new_rep, h_infer, "inputs"); 2322 UpdateRepresentation(new_rep, h_infer, "inputs");
2304 // When the operation has information about its own output type, don't look 2323 // When the operation has information about its own output type, don't look
2305 // at uses. 2324 // at uses.
2306 if (!observed_output_representation_.IsNone()) return; 2325 if (!observed_output_representation_.IsNone()) return;
2307 new_rep = RepresentationFromUses(); 2326 new_rep = RepresentationFromUses();
2308 UpdateRepresentation(new_rep, h_infer, "uses"); 2327 UpdateRepresentation(new_rep, h_infer, "uses");
2328 new_rep = RepresentationFromUseRequirements();
2329 if (new_rep.fits_into(Representation::Integer32())) {
2330 UpdateRepresentation(new_rep, h_infer, "use requirements");
2331 }
2309 } 2332 }
2310 2333
2311 2334
2312 bool HBinaryOperation::IgnoreObservedOutputRepresentation( 2335 bool HBinaryOperation::IgnoreObservedOutputRepresentation(
2313 Representation current_rep) { 2336 Representation current_rep) {
2314 return observed_output_representation_.IsDouble() && 2337 return observed_output_representation_.IsDouble() &&
2315 current_rep.IsInteger32() && 2338 current_rep.IsInteger32() &&
2316 // Mul in Integer32 mode would be too precise. 2339 // Mul in Integer32 mode would be too precise.
2317 !this->IsMul() && 2340 !this->IsMul() &&
2318 CheckUsesForFlag(kTruncatingToInt32); 2341 CheckUsesForFlag(kTruncatingToInt32);
(...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after
3655 3678
3656 Representation HPhi::RepresentationFromInputs() { 3679 Representation HPhi::RepresentationFromInputs() {
3657 Representation r = Representation::None(); 3680 Representation r = Representation::None();
3658 for (int i = 0; i < OperandCount(); ++i) { 3681 for (int i = 0; i < OperandCount(); ++i) {
3659 r = r.generalize(OperandAt(i)->KnownOptimalRepresentation()); 3682 r = r.generalize(OperandAt(i)->KnownOptimalRepresentation());
3660 } 3683 }
3661 return r; 3684 return r;
3662 } 3685 }
3663 3686
3664 3687
3665 Representation HPhi::RepresentationFromUseRequirements() { 3688 // Returns a representation if all uses agree on the same representation.
3666 Representation all_uses_require = Representation::None(); 3689 // Integer32 is also returned when some uses are Smi but others are Integer32.
3667 bool all_uses_require_the_same = true; 3690 Representation HValue::RepresentationFromUseRequirements() {
3691 Representation rep = Representation::None();
3668 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 3692 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
3669 // We check for observed_input_representation elsewhere. 3693 // We check for observed_input_representation elsewhere.
3670 Representation use_rep = 3694 Representation use_rep =
3671 it.value()->RequiredInputRepresentation(it.index()); 3695 it.value()->RequiredInputRepresentation(it.index());
3672 // No useful info from this use -> look at the next one. 3696 if (rep.IsNone()) {
3673 if (use_rep.IsNone()) { 3697 rep = use_rep;
3674 continue; 3698 continue;
3675 } 3699 }
3676 if (use_rep.Equals(all_uses_require)) { 3700 if (use_rep.IsNone() || rep.Equals(use_rep)) continue;
3701 if (rep.generalize(use_rep).IsInteger32()) {
3702 rep = Representation::Integer32();
3677 continue; 3703 continue;
3678 } 3704 }
3679 // This use's representation contradicts what we've seen so far. 3705 return Representation::None();
3680 if (!all_uses_require.IsNone()) {
3681 ASSERT(!use_rep.Equals(all_uses_require));
3682 all_uses_require_the_same = false;
3683 break;
3684 }
3685 // Otherwise, initialize observed representation.
3686 all_uses_require = use_rep;
3687 } 3706 }
3688 if (all_uses_require_the_same) { 3707 return rep;
3689 return all_uses_require;
3690 }
3691
3692 return Representation::None();
3693 } 3708 }
3694 3709
3695 3710
3696 // Node-specific verification code is only included in debug mode. 3711 // Node-specific verification code is only included in debug mode.
3697 #ifdef DEBUG 3712 #ifdef DEBUG
3698 3713
3699 void HPhi::Verify() { 3714 void HPhi::Verify() {
3700 ASSERT(OperandCount() == block()->predecessors()->length()); 3715 ASSERT(OperandCount() == block()->predecessors()->length());
3701 for (int i = 0; i < OperandCount(); ++i) { 3716 for (int i = 0; i < OperandCount(); ++i) {
3702 HValue* value = OperandAt(i); 3717 HValue* value = OperandAt(i);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
3857 case kBackingStore: 3872 case kBackingStore:
3858 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); 3873 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString());
3859 stream->Add("[backing-store]"); 3874 stream->Add("[backing-store]");
3860 break; 3875 break;
3861 } 3876 }
3862 3877
3863 stream->Add("@%d", offset()); 3878 stream->Add("@%d", offset());
3864 } 3879 }
3865 3880
3866 } } // namespace v8::internal 3881 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698