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

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

Issue 22715004: Version 3.20.15 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Add TypedArray API and correctness patches r16033 and r16084 Created 7 years, 4 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/hydrogen-uint32-analysis.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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 void HValue::AddDependantsToWorklist(HInferRepresentationPhase* h_infer) { 142 void HValue::AddDependantsToWorklist(HInferRepresentationPhase* h_infer) {
143 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 143 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
144 h_infer->AddToWorklist(it.value()); 144 h_infer->AddToWorklist(it.value());
145 } 145 }
146 for (int i = 0; i < OperandCount(); ++i) { 146 for (int i = 0; i < OperandCount(); ++i) {
147 h_infer->AddToWorklist(OperandAt(i)); 147 h_infer->AddToWorklist(OperandAt(i));
148 } 148 }
149 } 149 }
150 150
151 151
152 // This method is recursive but it is guaranteed to terminate because
153 // RedefinedOperand() always dominates "this".
154 bool HValue::IsRelationTrue(NumericRelation relation,
155 HValue* other,
156 int offset,
157 int scale) {
158 if (this == other) {
159 return scale == 0 && relation.IsExtendable(offset);
160 }
161
162 // Test the direct relation.
163 if (IsRelationTrueInternal(relation, other, offset, scale)) return true;
164
165 // If scale is 0 try the reversed relation.
166 if (scale == 0 &&
167 // TODO(mmassi): do we need the full, recursive IsRelationTrue?
168 other->IsRelationTrueInternal(relation.Reversed(), this, -offset)) {
169 return true;
170 }
171
172 // Try decomposition (but do not accept scaled compounds).
173 DecompositionResult decomposition;
174 if (TryDecompose(&decomposition) &&
175 decomposition.scale() == 0 &&
176 decomposition.base()->IsRelationTrue(relation, other,
177 offset + decomposition.offset(),
178 scale)) {
179 return true;
180 }
181
182 // Pass the request to the redefined value.
183 HValue* redefined = RedefinedOperand();
184 return redefined != NULL && redefined->IsRelationTrue(relation, other,
185 offset, scale);
186 }
187
188
189 bool HValue::TryGuaranteeRange(HValue* upper_bound) {
190 RangeEvaluationContext context = RangeEvaluationContext(this, upper_bound);
191 TryGuaranteeRangeRecursive(&context);
192 bool result = context.is_range_satisfied();
193 if (result) {
194 context.lower_bound_guarantee()->SetResponsibilityForRange(DIRECTION_LOWER);
195 context.upper_bound_guarantee()->SetResponsibilityForRange(DIRECTION_UPPER);
196 }
197 return result;
198 }
199
200
201 void HValue::TryGuaranteeRangeRecursive(RangeEvaluationContext* context) {
202 // Check if we already know that this value satisfies the lower bound.
203 if (context->lower_bound_guarantee() == NULL) {
204 if (IsRelationTrueInternal(NumericRelation::Ge(), context->lower_bound(),
205 context->offset(), context->scale())) {
206 context->set_lower_bound_guarantee(this);
207 }
208 }
209
210 // Check if we already know that this value satisfies the upper bound.
211 if (context->upper_bound_guarantee() == NULL) {
212 if (IsRelationTrueInternal(NumericRelation::Lt(), context->upper_bound(),
213 context->offset(), context->scale()) ||
214 (context->scale() == 0 &&
215 context->upper_bound()->IsRelationTrue(NumericRelation::Gt(),
216 this, -context->offset()))) {
217 context->set_upper_bound_guarantee(this);
218 }
219 }
220
221 if (context->is_range_satisfied()) return;
222
223 // See if our RedefinedOperand() satisfies the constraints.
224 if (RedefinedOperand() != NULL) {
225 RedefinedOperand()->TryGuaranteeRangeRecursive(context);
226 }
227 if (context->is_range_satisfied()) return;
228
229 // See if the constraints can be satisfied by decomposition.
230 DecompositionResult decomposition;
231 if (TryDecompose(&decomposition)) {
232 context->swap_candidate(&decomposition);
233 context->candidate()->TryGuaranteeRangeRecursive(context);
234 context->swap_candidate(&decomposition);
235 }
236 if (context->is_range_satisfied()) return;
237
238 // Try to modify this to satisfy the constraint.
239
240 TryGuaranteeRangeChanging(context);
241 }
242
243
244 RangeEvaluationContext::RangeEvaluationContext(HValue* value, HValue* upper)
245 : lower_bound_(upper->block()->graph()->GetConstant0()),
246 lower_bound_guarantee_(NULL),
247 candidate_(value),
248 upper_bound_(upper),
249 upper_bound_guarantee_(NULL),
250 offset_(0),
251 scale_(0) {
252 }
253
254
255 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) {
256 return guarantee->IsBoundsCheckBaseIndexInformation()
257 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check()
258 : guarantee;
259 }
260
261
152 static int32_t ConvertAndSetOverflow(Representation r, 262 static int32_t ConvertAndSetOverflow(Representation r,
153 int64_t result, 263 int64_t result,
154 bool* overflow) { 264 bool* overflow) {
155 if (r.IsSmi()) { 265 if (r.IsSmi()) {
156 if (result > Smi::kMaxValue) { 266 if (result > Smi::kMaxValue) {
157 *overflow = true; 267 *overflow = true;
158 return Smi::kMaxValue; 268 return Smi::kMaxValue;
159 } 269 }
160 if (result < Smi::kMinValue) { 270 if (result < Smi::kMinValue) {
161 *overflow = true; 271 *overflow = true;
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 result = HType::Boolean(); 477 result = HType::Boolean();
368 } else if (value->IsJSObject()) { 478 } else if (value->IsJSObject()) {
369 result = HType::JSObject(); 479 result = HType::JSObject();
370 } else if (value->IsJSArray()) { 480 } else if (value->IsJSArray()) {
371 result = HType::JSArray(); 481 result = HType::JSArray();
372 } 482 }
373 return result; 483 return result;
374 } 484 }
375 485
376 486
487 bool HValue::Dominates(HValue* dominator, HValue* dominated) {
488 if (dominator->block() != dominated->block()) {
489 // If they are in different blocks we can use the dominance relation
490 // between the blocks.
491 return dominator->block()->Dominates(dominated->block());
492 } else {
493 // Otherwise we must see which instruction comes first, considering
494 // that phis always precede regular instructions.
495 if (dominator->IsInstruction()) {
496 if (dominated->IsInstruction()) {
497 for (HInstruction* next = HInstruction::cast(dominator)->next();
498 next != NULL;
499 next = next->next()) {
500 if (next == dominated) return true;
501 }
502 return false;
503 } else if (dominated->IsPhi()) {
504 return false;
505 } else {
506 UNREACHABLE();
507 }
508 } else if (dominator->IsPhi()) {
509 if (dominated->IsInstruction()) {
510 return true;
511 } else {
512 // We cannot compare which phi comes first.
513 UNREACHABLE();
514 }
515 } else {
516 UNREACHABLE();
517 }
518 return false;
519 }
520 }
521
522
523 bool HValue::TestDominanceUsingProcessedFlag(HValue* dominator,
524 HValue* dominated) {
525 if (dominator->block() != dominated->block()) {
526 return dominator->block()->Dominates(dominated->block());
527 } else {
528 // If both arguments are in the same block we check if dominator is a phi
529 // or if dominated has not already been processed: in either case we know
530 // that dominator precedes dominated.
531 return dominator->IsPhi() || !dominated->CheckFlag(kIDefsProcessingDone);
532 }
533 }
534
535
377 bool HValue::IsDefinedAfter(HBasicBlock* other) const { 536 bool HValue::IsDefinedAfter(HBasicBlock* other) const {
378 return block()->block_id() > other->block_id(); 537 return block()->block_id() > other->block_id();
379 } 538 }
380 539
381 540
382 HUseListNode* HUseListNode::tail() { 541 HUseListNode* HUseListNode::tail() {
383 // Skip and remove dead items in the use list. 542 // Skip and remove dead items in the use list.
384 while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) { 543 while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) {
385 tail_ = tail_->tail_; 544 tail_ = tail_->tail_;
386 } 545 }
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 // Verify that all uses are in the graph. 953 // Verify that all uses are in the graph.
795 for (HUseIterator use = uses(); !use.Done(); use.Advance()) { 954 for (HUseIterator use = uses(); !use.Done(); use.Advance()) {
796 if (use.value()->IsInstruction()) { 955 if (use.value()->IsInstruction()) {
797 ASSERT(HInstruction::cast(use.value())->IsLinked()); 956 ASSERT(HInstruction::cast(use.value())->IsLinked());
798 } 957 }
799 } 958 }
800 } 959 }
801 #endif 960 #endif
802 961
803 962
963 HNumericConstraint* HNumericConstraint::AddToGraph(
964 HValue* constrained_value,
965 NumericRelation relation,
966 HValue* related_value,
967 HInstruction* insertion_point) {
968 if (insertion_point == NULL) {
969 if (constrained_value->IsInstruction()) {
970 insertion_point = HInstruction::cast(constrained_value);
971 } else if (constrained_value->IsPhi()) {
972 insertion_point = constrained_value->block()->first();
973 } else {
974 UNREACHABLE();
975 }
976 }
977 HNumericConstraint* result =
978 new(insertion_point->block()->zone()) HNumericConstraint(
979 constrained_value, relation, related_value);
980 result->InsertAfter(insertion_point);
981 return result;
982 }
983
984
985 void HNumericConstraint::PrintDataTo(StringStream* stream) {
986 stream->Add("(");
987 constrained_value()->PrintNameTo(stream);
988 stream->Add(" %s ", relation().Mnemonic());
989 related_value()->PrintNameTo(stream);
990 stream->Add(")");
991 }
992
993
994 HInductionVariableAnnotation* HInductionVariableAnnotation::AddToGraph(
995 HPhi* phi,
996 NumericRelation relation,
997 int operand_index) {
998 HInductionVariableAnnotation* result =
999 new(phi->block()->zone()) HInductionVariableAnnotation(phi, relation,
1000 operand_index);
1001 result->InsertAfter(phi->block()->first());
1002 return result;
1003 }
1004
1005
1006 void HInductionVariableAnnotation::PrintDataTo(StringStream* stream) {
1007 stream->Add("(");
1008 RedefinedOperand()->PrintNameTo(stream);
1009 stream->Add(" %s ", relation().Mnemonic());
1010 induction_base()->PrintNameTo(stream);
1011 stream->Add(")");
1012 }
1013
1014
804 void HDummyUse::PrintDataTo(StringStream* stream) { 1015 void HDummyUse::PrintDataTo(StringStream* stream) {
805 value()->PrintNameTo(stream); 1016 value()->PrintNameTo(stream);
806 } 1017 }
807 1018
808 1019
809 void HEnvironmentMarker::PrintDataTo(StringStream* stream) { 1020 void HEnvironmentMarker::PrintDataTo(StringStream* stream) {
810 stream->Add("%s var[%d]", kind() == BIND ? "bind" : "lookup", index()); 1021 stream->Add("%s var[%d]", kind() == BIND ? "bind" : "lookup", index());
811 } 1022 }
812 1023
813 1024
814 void HUnaryCall::PrintDataTo(StringStream* stream) { 1025 void HUnaryCall::PrintDataTo(StringStream* stream) {
815 value()->PrintNameTo(stream); 1026 value()->PrintNameTo(stream);
816 stream->Add(" "); 1027 stream->Add(" ");
817 stream->Add("#%d", argument_count()); 1028 stream->Add("#%d", argument_count());
818 } 1029 }
819 1030
820 1031
821 void HBinaryCall::PrintDataTo(StringStream* stream) { 1032 void HBinaryCall::PrintDataTo(StringStream* stream) {
822 first()->PrintNameTo(stream); 1033 first()->PrintNameTo(stream);
823 stream->Add(" "); 1034 stream->Add(" ");
824 second()->PrintNameTo(stream); 1035 second()->PrintNameTo(stream);
825 stream->Add(" "); 1036 stream->Add(" ");
826 stream->Add("#%d", argument_count()); 1037 stream->Add("#%d", argument_count());
827 } 1038 }
828 1039
829 1040
1041 void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
1042 if (context->candidate()->ActualValue() != base()->ActualValue() ||
1043 context->scale() < scale()) {
1044 return;
1045 }
1046
1047 // TODO(mmassi)
1048 // Instead of checking for "same basic block" we should check for
1049 // "dominates and postdominates".
1050 if (context->upper_bound() == length() &&
1051 context->lower_bound_guarantee() != NULL &&
1052 context->lower_bound_guarantee() != this &&
1053 context->lower_bound_guarantee()->block() != block() &&
1054 offset() < context->offset() &&
1055 index_can_increase() &&
1056 context->upper_bound_guarantee() == NULL) {
1057 offset_ = context->offset();
1058 SetResponsibilityForRange(DIRECTION_UPPER);
1059 context->set_upper_bound_guarantee(this);
1060 isolate()->counters()->bounds_checks_eliminated()->Increment();
1061 } else if (context->upper_bound_guarantee() != NULL &&
1062 context->upper_bound_guarantee() != this &&
1063 context->upper_bound_guarantee()->block() != block() &&
1064 offset() > context->offset() &&
1065 index_can_decrease() &&
1066 context->lower_bound_guarantee() == NULL) {
1067 offset_ = context->offset();
1068 SetResponsibilityForRange(DIRECTION_LOWER);
1069 context->set_lower_bound_guarantee(this);
1070 isolate()->counters()->bounds_checks_eliminated()->Increment();
1071 }
1072 }
1073
1074
830 void HBoundsCheck::ApplyIndexChange() { 1075 void HBoundsCheck::ApplyIndexChange() {
831 if (skip_check()) return; 1076 if (skip_check()) return;
832 1077
833 DecompositionResult decomposition; 1078 DecompositionResult decomposition;
834 bool index_is_decomposable = index()->TryDecompose(&decomposition); 1079 bool index_is_decomposable = index()->TryDecompose(&decomposition);
835 if (index_is_decomposable) { 1080 if (index_is_decomposable) {
836 ASSERT(decomposition.base() == base()); 1081 ASSERT(decomposition.base() == base());
837 if (decomposition.offset() == offset() && 1082 if (decomposition.offset() == offset() &&
838 decomposition.scale() == scale()) return; 1083 decomposition.scale() == scale()) return;
839 } else { 1084 } else {
(...skipping 27 matching lines...) Expand all
867 sar->InsertBefore(this); 1112 sar->InsertBefore(this);
868 sar->AssumeRepresentation(index()->representation()); 1113 sar->AssumeRepresentation(index()->representation());
869 current_index = sar; 1114 current_index = sar;
870 } 1115 }
871 1116
872 SetOperandAt(0, current_index); 1117 SetOperandAt(0, current_index);
873 1118
874 base_ = NULL; 1119 base_ = NULL;
875 offset_ = 0; 1120 offset_ = 0;
876 scale_ = 0; 1121 scale_ = 0;
1122 responsibility_direction_ = DIRECTION_NONE;
877 } 1123 }
878 1124
879 1125
1126 void HBoundsCheck::AddInformativeDefinitions() {
1127 // TODO(mmassi): Executing this code during AddInformativeDefinitions
1128 // is a hack. Move it to some other HPhase.
1129 if (FLAG_array_bounds_checks_elimination) {
1130 if (index()->TryGuaranteeRange(length())) {
1131 set_skip_check();
1132 }
1133 if (DetectCompoundIndex()) {
1134 HBoundsCheckBaseIndexInformation* base_index_info =
1135 new(block()->graph()->zone())
1136 HBoundsCheckBaseIndexInformation(this);
1137 base_index_info->InsertAfter(this);
1138 }
1139 }
1140 }
1141
1142
1143 bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation,
1144 HValue* related_value,
1145 int offset,
1146 int scale) {
1147 if (related_value == length()) {
1148 // A HBoundsCheck is smaller than the length it compared against.
1149 return NumericRelation::Lt().CompoundImplies(relation, 0, 0, offset, scale);
1150 } else if (related_value == block()->graph()->GetConstant0()) {
1151 // A HBoundsCheck is greater than or equal to zero.
1152 return NumericRelation::Ge().CompoundImplies(relation, 0, 0, offset, scale);
1153 } else {
1154 return false;
1155 }
1156 }
1157
1158
880 void HBoundsCheck::PrintDataTo(StringStream* stream) { 1159 void HBoundsCheck::PrintDataTo(StringStream* stream) {
881 index()->PrintNameTo(stream); 1160 index()->PrintNameTo(stream);
882 stream->Add(" "); 1161 stream->Add(" ");
883 length()->PrintNameTo(stream); 1162 length()->PrintNameTo(stream);
884 if (base() != NULL && (offset() != 0 || scale() != 0)) { 1163 if (base() != NULL && (offset() != 0 || scale() != 0)) {
885 stream->Add(" base: (("); 1164 stream->Add(" base: ((");
886 if (base() != index()) { 1165 if (base() != index()) {
887 index()->PrintNameTo(stream); 1166 index()->PrintNameTo(stream);
888 } else { 1167 } else {
889 stream->Add("index"); 1168 stream->Add("index");
(...skipping 19 matching lines...) Expand all
909 length_rep = Representation::Smi(); 1188 length_rep = Representation::Smi();
910 } 1189 }
911 Representation r = index_rep.generalize(length_rep); 1190 Representation r = index_rep.generalize(length_rep);
912 if (r.is_more_general_than(Representation::Integer32())) { 1191 if (r.is_more_general_than(Representation::Integer32())) {
913 r = Representation::Integer32(); 1192 r = Representation::Integer32();
914 } 1193 }
915 UpdateRepresentation(r, h_infer, "boundscheck"); 1194 UpdateRepresentation(r, h_infer, "boundscheck");
916 } 1195 }
917 1196
918 1197
1198 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal(
1199 NumericRelation relation,
1200 HValue* related_value,
1201 int offset,
1202 int scale) {
1203 if (related_value == bounds_check()->length()) {
1204 return NumericRelation::Lt().CompoundImplies(
1205 relation,
1206 bounds_check()->offset(), bounds_check()->scale(), offset, scale);
1207 } else if (related_value == block()->graph()->GetConstant0()) {
1208 return NumericRelation::Ge().CompoundImplies(
1209 relation,
1210 bounds_check()->offset(), bounds_check()->scale(), offset, scale);
1211 } else {
1212 return false;
1213 }
1214 }
1215
1216
919 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) { 1217 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) {
920 stream->Add("base: "); 1218 stream->Add("base: ");
921 base_index()->PrintNameTo(stream); 1219 base_index()->PrintNameTo(stream);
922 stream->Add(", check: "); 1220 stream->Add(", check: ");
923 base_index()->PrintNameTo(stream); 1221 base_index()->PrintNameTo(stream);
924 } 1222 }
925 1223
926 1224
927 void HCallConstantFunction::PrintDataTo(StringStream* stream) { 1225 void HCallConstantFunction::PrintDataTo(StringStream* stream) {
928 if (IsApplyFunction()) { 1226 if (IsApplyFunction()) {
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 } 1446 }
1149 1447
1150 1448
1151 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { 1449 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) {
1152 object()->PrintNameTo(stream); 1450 object()->PrintNameTo(stream);
1153 stream->Add(" "); 1451 stream->Add(" ");
1154 index()->PrintNameTo(stream); 1452 index()->PrintNameTo(stream);
1155 } 1453 }
1156 1454
1157 1455
1158 static bool MatchLeftIsOnes(HValue* l, HValue* r, HValue** negated) {
1159 if (!l->EqualsInteger32Constant(~0)) return false;
1160 *negated = r;
1161 return true;
1162 }
1163
1164
1165 static bool MatchNegationViaXor(HValue* instr, HValue** negated) {
1166 if (!instr->IsBitwise()) return false;
1167 HBitwise* b = HBitwise::cast(instr);
1168 return (b->op() == Token::BIT_XOR) &&
1169 (MatchLeftIsOnes(b->left(), b->right(), negated) ||
1170 MatchLeftIsOnes(b->right(), b->left(), negated));
1171 }
1172
1173
1174 static bool MatchDoubleNegation(HValue* instr, HValue** arg) {
1175 HValue* negated;
1176 return MatchNegationViaXor(instr, &negated) &&
1177 MatchNegationViaXor(negated, arg);
1178 }
1179
1180
1181 HValue* HBitwise::Canonicalize() { 1456 HValue* HBitwise::Canonicalize() {
1182 if (!representation().IsSmiOrInteger32()) return this; 1457 if (!representation().IsSmiOrInteger32()) return this;
1183 // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. 1458 // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x.
1184 int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0; 1459 int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0;
1185 if (left()->EqualsInteger32Constant(nop_constant) && 1460 if (left()->EqualsInteger32Constant(nop_constant) &&
1186 !right()->CheckFlag(kUint32)) { 1461 !right()->CheckFlag(kUint32)) {
1187 return right(); 1462 return right();
1188 } 1463 }
1189 if (right()->EqualsInteger32Constant(nop_constant) && 1464 if (right()->EqualsInteger32Constant(nop_constant) &&
1190 !left()->CheckFlag(kUint32)) { 1465 !left()->CheckFlag(kUint32)) {
1191 return left(); 1466 return left();
1192 } 1467 }
1193 // Optimize double negation, a common pattern used for ToInt32(x). 1468 return this;
1194 HValue* arg; 1469 }
1195 if (MatchDoubleNegation(this, &arg) && !arg->CheckFlag(kUint32)) { 1470
1196 return arg; 1471
1472 HValue* HBitNot::Canonicalize() {
1473 // Optimize ~~x, a common pattern used for ToInt32(x).
1474 if (value()->IsBitNot()) {
1475 HValue* result = HBitNot::cast(value())->value();
1476 ASSERT(result->representation().IsInteger32());
1477 if (!result->CheckFlag(kUint32)) {
1478 return result;
1479 }
1197 } 1480 }
1198 return this; 1481 return this;
1199 } 1482 }
1200 1483
1201 1484
1202 static bool IsIdentityOperation(HValue* arg1, HValue* arg2, int32_t identity) { 1485 static bool IsIdentityOperation(HValue* arg1, HValue* arg2, int32_t identity) {
1203 return arg1->representation().IsSpecialization() && 1486 return arg1->representation().IsSpecialization() &&
1204 arg2->EqualsInteger32Constant(identity); 1487 arg2->EqualsInteger32Constant(identity);
1205 } 1488 }
1206 1489
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 1680
1398 1681
1399 void HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect, 1682 void HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect,
1400 HValue* dominator) { 1683 HValue* dominator) {
1401 ASSERT(side_effect == kChangesMaps); 1684 ASSERT(side_effect == kChangesMaps);
1402 // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once 1685 // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once
1403 // type information is rich enough we should generalize this to any HType 1686 // type information is rich enough we should generalize this to any HType
1404 // for which the map is known. 1687 // for which the map is known.
1405 if (HasNoUses() && dominator->IsStoreNamedField()) { 1688 if (HasNoUses() && dominator->IsStoreNamedField()) {
1406 HStoreNamedField* store = HStoreNamedField::cast(dominator); 1689 HStoreNamedField* store = HStoreNamedField::cast(dominator);
1407 if (!store->has_transition() || store->object() != value()) return; 1690 UniqueValueId map_unique_id = store->transition_unique_id();
1408 HConstant* transition = HConstant::cast(store->transition()); 1691 if (!map_unique_id.IsInitialized() || store->object() != value()) return;
1409 for (int i = 0; i < map_set()->length(); i++) { 1692 for (int i = 0; i < map_set()->length(); i++) {
1410 if (transition->UniqueValueIdsMatch(map_unique_ids_.at(i))) { 1693 if (map_unique_id == map_unique_ids_.at(i)) {
1411 DeleteAndReplaceWith(NULL); 1694 DeleteAndReplaceWith(NULL);
1412 return; 1695 return;
1413 } 1696 }
1414 } 1697 }
1415 } 1698 }
1416 } 1699 }
1417 1700
1418 1701
1419 void HCheckMaps::PrintDataTo(StringStream* stream) { 1702 void HCheckMaps::PrintDataTo(StringStream* stream) {
1420 value()->PrintNameTo(stream); 1703 value()->PrintNameTo(stream);
(...skipping 30 matching lines...) Expand all
1451 return ""; 1734 return "";
1452 } 1735 }
1453 1736
1454 1737
1455 void HCheckInstanceType::PrintDataTo(StringStream* stream) { 1738 void HCheckInstanceType::PrintDataTo(StringStream* stream) {
1456 stream->Add("%s ", GetCheckName()); 1739 stream->Add("%s ", GetCheckName());
1457 HUnaryOperation::PrintDataTo(stream); 1740 HUnaryOperation::PrintDataTo(stream);
1458 } 1741 }
1459 1742
1460 1743
1744 void HCheckPrototypeMaps::PrintDataTo(StringStream* stream) {
1745 stream->Add("[receiver_prototype=%p,holder=%p]%s",
1746 *prototypes_.first(), *prototypes_.last(),
1747 CanOmitPrototypeChecks() ? " (omitted)" : "");
1748 }
1749
1750
1461 void HCallStub::PrintDataTo(StringStream* stream) { 1751 void HCallStub::PrintDataTo(StringStream* stream) {
1462 stream->Add("%s ", 1752 stream->Add("%s ",
1463 CodeStub::MajorName(major_key_, false)); 1753 CodeStub::MajorName(major_key_, false));
1464 HUnaryCall::PrintDataTo(stream); 1754 HUnaryCall::PrintDataTo(stream);
1465 } 1755 }
1466 1756
1467 1757
1468 void HInstanceOf::PrintDataTo(StringStream* stream) { 1758 void HInstanceOf::PrintDataTo(StringStream* stream) {
1469 left()->PrintNameTo(stream); 1759 left()->PrintNameTo(stream);
1470 stream->Add(" "); 1760 stream->Add(" ");
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1653 if (!b->CanBeZero()) { 1943 if (!b->CanBeZero()) {
1654 ClearFlag(HValue::kCanBeDivByZero); 1944 ClearFlag(HValue::kCanBeDivByZero);
1655 } 1945 }
1656 return result; 1946 return result;
1657 } else { 1947 } else {
1658 return HValue::InferRange(zone); 1948 return HValue::InferRange(zone);
1659 } 1949 }
1660 } 1950 }
1661 1951
1662 1952
1953 void HPhi::AddInformativeDefinitions() {
1954 if (OperandCount() == 2) {
1955 // If one of the operands is an OSR block give up (this cannot be an
1956 // induction variable).
1957 if (OperandAt(0)->block()->is_osr_entry() ||
1958 OperandAt(1)->block()->is_osr_entry()) return;
1959
1960 for (int operand_index = 0; operand_index < 2; operand_index++) {
1961 int other_operand_index = (operand_index + 1) % 2;
1962
1963 static NumericRelation relations[] = {
1964 NumericRelation::Ge(),
1965 NumericRelation::Le()
1966 };
1967
1968 // Check if this phi is an induction variable. If, e.g., we know that
1969 // its first input is greater than the phi itself, then that must be
1970 // the back edge, and the phi is always greater than its second input.
1971 for (int relation_index = 0; relation_index < 2; relation_index++) {
1972 if (OperandAt(operand_index)->IsRelationTrue(relations[relation_index],
1973 this)) {
1974 HInductionVariableAnnotation::AddToGraph(this,
1975 relations[relation_index],
1976 other_operand_index);
1977 }
1978 }
1979 }
1980 }
1981 }
1982
1983
1984 bool HPhi::IsRelationTrueInternal(NumericRelation relation,
1985 HValue* other,
1986 int offset,
1987 int scale) {
1988 if (CheckFlag(kNumericConstraintEvaluationInProgress)) return false;
1989
1990 SetFlag(kNumericConstraintEvaluationInProgress);
1991 bool result = true;
1992 for (int i = 0; i < OperandCount(); i++) {
1993 // Skip OSR entry blocks
1994 if (OperandAt(i)->block()->is_osr_entry()) continue;
1995
1996 if (!OperandAt(i)->IsRelationTrue(relation, other, offset, scale)) {
1997 result = false;
1998 break;
1999 }
2000 }
2001 ClearFlag(kNumericConstraintEvaluationInProgress);
2002
2003 return result;
2004 }
2005
2006
1663 InductionVariableData* InductionVariableData::ExaminePhi(HPhi* phi) { 2007 InductionVariableData* InductionVariableData::ExaminePhi(HPhi* phi) {
1664 if (phi->block()->loop_information() == NULL) return NULL; 2008 if (phi->block()->loop_information() == NULL) return NULL;
1665 if (phi->OperandCount() != 2) return NULL; 2009 if (phi->OperandCount() != 2) return NULL;
1666 int32_t candidate_increment; 2010 int32_t candidate_increment;
1667 2011
1668 candidate_increment = ComputeIncrement(phi, phi->OperandAt(0)); 2012 candidate_increment = ComputeIncrement(phi, phi->OperandAt(0));
1669 if (candidate_increment != 0) { 2013 if (candidate_increment != 0) {
1670 return new(phi->block()->graph()->zone()) 2014 return new(phi->block()->graph()->zone())
1671 InductionVariableData(phi, phi->OperandAt(1), candidate_increment); 2015 InductionVariableData(phi, phi->OperandAt(1), candidate_increment);
1672 } 2016 }
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
2404 has_external_reference_value_(true), 2748 has_external_reference_value_(true),
2405 is_internalized_string_(false), 2749 is_internalized_string_(false),
2406 is_not_in_new_space_(true), 2750 is_not_in_new_space_(true),
2407 is_cell_(false), 2751 is_cell_(false),
2408 boolean_value_(true), 2752 boolean_value_(true),
2409 external_reference_value_(reference) { 2753 external_reference_value_(reference) {
2410 Initialize(Representation::External()); 2754 Initialize(Representation::External());
2411 } 2755 }
2412 2756
2413 2757
2414 static void PrepareConstant(Handle<Object> object) {
2415 if (!object->IsJSObject()) return;
2416 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
2417 if (!js_object->map()->is_deprecated()) return;
2418 JSObject::TryMigrateInstance(js_object);
2419 }
2420
2421
2422 void HConstant::Initialize(Representation r) { 2758 void HConstant::Initialize(Representation r) {
2423 if (r.IsNone()) { 2759 if (r.IsNone()) {
2424 if (has_smi_value_ && kSmiValueSize == 31) { 2760 if (has_smi_value_ && kSmiValueSize == 31) {
2425 r = Representation::Smi(); 2761 r = Representation::Smi();
2426 } else if (has_int32_value_) { 2762 } else if (has_int32_value_) {
2427 r = Representation::Integer32(); 2763 r = Representation::Integer32();
2428 } else if (has_double_value_) { 2764 } else if (has_double_value_) {
2429 r = Representation::Double(); 2765 r = Representation::Double();
2430 } else if (has_external_reference_value_) { 2766 } else if (has_external_reference_value_) {
2431 r = Representation::External(); 2767 r = Representation::External();
2432 } else { 2768 } else {
2433 PrepareConstant(handle_);
2434 r = Representation::Tagged(); 2769 r = Representation::Tagged();
2435 } 2770 }
2436 } 2771 }
2437 set_representation(r); 2772 set_representation(r);
2438 SetFlag(kUseGVN); 2773 SetFlag(kUseGVN);
2439 } 2774 }
2440 2775
2441 2776
2442 bool HConstant::EmitAtUses() { 2777 bool HConstant::EmitAtUses() {
2443 ASSERT(IsLinked()); 2778 ASSERT(IsLinked());
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
2748 } 3083 }
2749 3084
2750 3085
2751 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { 3086 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) {
2752 stream->Add(Token::Name(token())); 3087 stream->Add(Token::Name(token()));
2753 stream->Add(" "); 3088 stream->Add(" ");
2754 HControlInstruction::PrintDataTo(stream); 3089 HControlInstruction::PrintDataTo(stream);
2755 } 3090 }
2756 3091
2757 3092
3093 void HCompareNumericAndBranch::AddInformativeDefinitions() {
3094 NumericRelation r = NumericRelation::FromToken(token());
3095 if (r.IsNone()) return;
3096
3097 HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first());
3098 HNumericConstraint::AddToGraph(
3099 left(), r.Negated(), right(), SuccessorAt(1)->first());
3100 }
3101
3102
2758 void HCompareNumericAndBranch::PrintDataTo(StringStream* stream) { 3103 void HCompareNumericAndBranch::PrintDataTo(StringStream* stream) {
2759 stream->Add(Token::Name(token())); 3104 stream->Add(Token::Name(token()));
2760 stream->Add(" "); 3105 stream->Add(" ");
2761 left()->PrintNameTo(stream); 3106 left()->PrintNameTo(stream);
2762 stream->Add(" "); 3107 stream->Add(" ");
2763 right()->PrintNameTo(stream); 3108 right()->PrintNameTo(stream);
2764 HControlInstruction::PrintDataTo(stream); 3109 HControlInstruction::PrintDataTo(stream);
2765 } 3110 }
2766 3111
2767 3112
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2946 3291
2947 3292
2948 HCheckMaps* HCheckMaps::New(Zone* zone, 3293 HCheckMaps* HCheckMaps::New(Zone* zone,
2949 HValue* context, 3294 HValue* context,
2950 HValue* value, 3295 HValue* value,
2951 Handle<Map> map, 3296 Handle<Map> map,
2952 CompilationInfo* info, 3297 CompilationInfo* info,
2953 HValue* typecheck) { 3298 HValue* typecheck) {
2954 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); 3299 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
2955 check_map->map_set_.Add(map, zone); 3300 check_map->map_set_.Add(map, zone);
2956 check_map->has_migration_target_ = map->is_migration_target();
2957 if (map->CanOmitMapChecks() && 3301 if (map->CanOmitMapChecks() &&
2958 value->IsConstant() && 3302 value->IsConstant() &&
2959 HConstant::cast(value)->InstanceOf(map)) { 3303 HConstant::cast(value)->InstanceOf(map)) {
2960 check_map->omit(info); 3304 check_map->omit(info);
2961 } 3305 }
2962 return check_map; 3306 return check_map;
2963 } 3307 }
2964 3308
2965 3309
2966 void HCheckMaps::FinalizeUniqueValueId() { 3310 void HCheckMaps::FinalizeUniqueValueId() {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
3171 3515
3172 3516
3173 void HStoreNamedField::PrintDataTo(StringStream* stream) { 3517 void HStoreNamedField::PrintDataTo(StringStream* stream) {
3174 object()->PrintNameTo(stream); 3518 object()->PrintNameTo(stream);
3175 access_.PrintTo(stream); 3519 access_.PrintTo(stream);
3176 stream->Add(" = "); 3520 stream->Add(" = ");
3177 value()->PrintNameTo(stream); 3521 value()->PrintNameTo(stream);
3178 if (NeedsWriteBarrier()) { 3522 if (NeedsWriteBarrier()) {
3179 stream->Add(" (write-barrier)"); 3523 stream->Add(" (write-barrier)");
3180 } 3524 }
3181 if (has_transition()) { 3525 if (!transition().is_null()) {
3182 stream->Add(" (transition map %p)", *transition_map()); 3526 stream->Add(" (transition map %p)", *transition());
3183 } 3527 }
3184 } 3528 }
3185 3529
3186 3530
3187 void HStoreKeyed::PrintDataTo(StringStream* stream) { 3531 void HStoreKeyed::PrintDataTo(StringStream* stream) {
3188 if (!is_external()) { 3532 if (!is_external()) {
3189 elements()->PrintNameTo(stream); 3533 elements()->PrintNameTo(stream);
3190 } else { 3534 } else {
3191 elements()->PrintNameTo(stream); 3535 elements()->PrintNameTo(stream);
3192 stream->Add("."); 3536 stream->Add(".");
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after
4135 break; 4479 break;
4136 case kExternalMemory: 4480 case kExternalMemory:
4137 stream->Add("[external-memory]"); 4481 stream->Add("[external-memory]");
4138 break; 4482 break;
4139 } 4483 }
4140 4484
4141 stream->Add("@%d", offset()); 4485 stream->Add("@%d", offset());
4142 } 4486 }
4143 4487
4144 } } // namespace v8::internal 4488 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/hydrogen-uint32-analysis.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698