Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 case kDouble: return "d"; | 61 case kDouble: return "d"; |
| 62 case kInteger32: return "i"; | 62 case kInteger32: return "i"; |
| 63 case kExternal: return "x"; | 63 case kExternal: return "x"; |
| 64 default: | 64 default: |
| 65 UNREACHABLE(); | 65 UNREACHABLE(); |
| 66 return NULL; | 66 return NULL; |
| 67 } | 67 } |
| 68 } | 68 } |
| 69 | 69 |
| 70 | 70 |
| 71 bool NumericRelationTable::IsInTable(int value_id, | |
| 72 NumericRelation relation, | |
| 73 int other_value_id, | |
| 74 int offset, | |
| 75 int scale, | |
| 76 int block_id, | |
| 77 bool* result) { | |
| 78 NumericRelationTableElement element(value_id, relation, other_value_id, | |
| 79 offset, scale, block_id, false); | |
| 80 int index = FindInsertionPoint(element, result); | |
| 81 return index < 0; | |
| 82 } | |
| 83 | |
| 84 | |
| 85 void NumericRelationTable::AddToTable(int value_id, | |
| 86 NumericRelation relation, | |
| 87 int other_value_id, | |
| 88 int offset, | |
| 89 int scale, | |
| 90 int block_id, | |
| 91 bool result) { | |
| 92 NumericRelationTableElement element(value_id, relation, other_value_id, | |
| 93 offset, scale, block_id, result); | |
| 94 bool res; | |
| 95 int index = FindInsertionPoint(element, &res); | |
| 96 if (index >= 0) { | |
| 97 Insert(element, index); | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 | |
| 102 void NumericRelationTable::Clear() { | |
| 103 table_.Clear(); | |
| 104 } | |
| 105 | |
| 106 | |
| 107 int NumericRelationTable::FindInsertionPoint( | |
| 108 const NumericRelationTableElement& element, | |
| 109 bool* result) { | |
| 110 int lower = 0; | |
| 111 int upper = table_.length(); | |
| 112 if (upper == 0) return 0; | |
| 113 | |
| 114 while (true) { | |
| 115 int middle = (lower + upper) >> 1; | |
| 116 | |
| 117 int comparison = element.Compare(table_.at(middle)); | |
| 118 if (comparison > 0) { | |
| 119 if (lower == middle) { | |
| 120 if (upper < table_.length()) { | |
| 121 if (element.Compare(table_.at(upper)) == 0) { | |
| 122 *result = table_.at(upper).result(); | |
| 123 return -1; | |
| 124 } else { | |
| 125 return upper; | |
| 126 } | |
| 127 } else { | |
| 128 return upper; | |
| 129 } | |
| 130 } else { | |
| 131 lower = middle; | |
| 132 } | |
| 133 } else if (comparison < 0) { | |
| 134 if (upper == middle) { | |
| 135 return middle; | |
| 136 } else { | |
| 137 upper = middle; | |
| 138 } | |
| 139 } else { | |
| 140 *result = table_.at(middle).result(); | |
| 141 return -1; | |
| 142 } | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 | |
| 147 void NumericRelationTable::Insert(const NumericRelationTableElement& element, | |
| 148 int index) { | |
| 149 table_.InsertAt(index, element, zone_); | |
| 150 } | |
| 151 | |
| 152 | |
| 71 int HValue::LoopWeight() const { | 153 int HValue::LoopWeight() const { |
| 72 const int w = FLAG_loop_weight; | 154 const int w = FLAG_loop_weight; |
| 73 static const int weights[] = { 1, w, w*w, w*w*w, w*w*w*w }; | 155 static const int weights[] = { 1, w, w*w, w*w*w, w*w*w*w }; |
| 74 return weights[Min(block()->LoopNestingDepth(), | 156 return weights[Min(block()->LoopNestingDepth(), |
| 75 static_cast<int>(ARRAY_SIZE(weights)-1))]; | 157 static_cast<int>(ARRAY_SIZE(weights)-1))]; |
| 76 } | 158 } |
| 77 | 159 |
| 78 | 160 |
| 79 Isolate* HValue::isolate() const { | 161 Isolate* HValue::isolate() const { |
| 80 ASSERT(block() != NULL); | 162 ASSERT(block() != NULL); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 160 void HValue::AddDependantsToWorklist(HInferRepresentation* h_infer) { | 242 void HValue::AddDependantsToWorklist(HInferRepresentation* h_infer) { |
| 161 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 243 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
| 162 h_infer->AddToWorklist(it.value()); | 244 h_infer->AddToWorklist(it.value()); |
| 163 } | 245 } |
| 164 for (int i = 0; i < OperandCount(); ++i) { | 246 for (int i = 0; i < OperandCount(); ++i) { |
| 165 h_infer->AddToWorklist(OperandAt(i)); | 247 h_infer->AddToWorklist(OperandAt(i)); |
| 166 } | 248 } |
| 167 } | 249 } |
| 168 | 250 |
| 169 | 251 |
| 170 // This method is recursive but it is guaranteed to terminate because | |
| 171 // RedefinedOperand() always dominates "this". | |
| 172 bool HValue::IsRelationTrue(NumericRelation relation, | 252 bool HValue::IsRelationTrue(NumericRelation relation, |
| 173 HValue* other, | 253 HValue* other, |
| 174 int offset, | 254 int offset, |
| 175 int scale) { | 255 int scale) { |
| 176 if (this == other) { | 256 bool result; |
| 177 return scale == 0 && relation.IsExtendable(offset); | 257 if (block()->graph()->HasRelationBeenEvaluated( |
| 258 this, relation, other, offset, scale, block(), &result)) { | |
| 259 return result; | |
| 260 } | |
| 261 | |
| 262 result = EvaluateRelationRecursively(relation, other, offset, scale); | |
| 263 | |
| 264 block()->graph()->AddRelationToTable( | |
| 265 this, relation, other, offset, scale, block(), result); | |
| 266 return result; | |
| 267 } | |
| 268 | |
| 269 | |
| 270 // This method is a recursive graph walk but it is guaranteed to terminate | |
| 271 // because RedefinedOperand() always dominates "this" and phis will check | |
| 272 // the "kNumericConstraintEvaluationInProgress" flag and never re-evaluate | |
| 273 // themselves. | |
| 274 bool HValue::EvaluateRelationRecursively(NumericRelation relation, | |
| 275 HValue* other, | |
| 276 int offset, | |
| 277 int scale) { | |
| 278 if (ActualValue() == other->ActualValue()) { | |
| 279 return scale == 0 && relation.ImpliedByEquality(offset); | |
| 178 } | 280 } |
| 179 | 281 |
| 180 // Test the direct relation. | 282 // Test the direct relation. |
| 181 if (IsRelationTrueInternal(relation, other, offset, scale)) return true; | 283 if (IsRelationTrueInternal(relation, other, offset, scale)) return true; |
| 182 | 284 |
| 183 // If scale is 0 try the reversed relation. | 285 // If scale is 0 try the reversed relation. |
| 184 if (scale == 0 && | 286 if (scale == 0 && |
| 185 // TODO(mmassi): do we need the full, recursive IsRelationTrue? | 287 // TODO(mmassi): do we need the full, recursive IsRelationTrue? |
| 186 other->IsRelationTrueInternal(relation.Reversed(), this, -offset)) { | 288 other->IsRelationTrueInternal(relation.Reversed(), this, -offset)) { |
| 187 return true; | 289 return true; |
| 188 } | 290 } |
| 189 | 291 |
| 190 // Try decomposition (but do not accept scaled compounds). | 292 // Try decomposition, but only if we are not scaled. |
| 191 DecompositionResult decomposition; | 293 DecompositionResult decomposition; |
| 192 if (TryDecompose(&decomposition) && | 294 if (scale == 0 && TryDecompose(&decomposition)) { |
| 193 decomposition.scale() == 0 && | 295 // Check if the compound is scaled. |
| 194 decomposition.base()->IsRelationTrue(relation, other, | 296 if (decomposition.scale() == 0) { |
| 195 offset + decomposition.offset(), | 297 // Non-scaled compounds can be handled normally. |
| 196 scale)) { | 298 if (decomposition.base()->IsRelationTrue( |
| 197 return true; | 299 relation, other, offset + decomposition.offset(), scale)) { |
| 300 return true; | |
| 301 } | |
| 302 } else if (decomposition.offset() == 0 && offset == 0) { | |
| 303 // We only have a scale value which means that we can apply chaining | |
| 304 // using relation extensibility: negative scales grow values (positive | |
| 305 // direction), positive scales make them smaller (negative direction). | |
| 306 // As a concrete example: "(x << 1) <= 0" <== "x <= 0". | |
| 307 int direction = -decomposition.scale(); | |
| 308 if (relation.IsExtendable(direction) && | |
| 309 decomposition.base()->IsRelationTrue(relation, other, 0, 0)) { | |
| 310 return true; | |
| 311 } | |
| 312 | |
| 313 } else { | |
| 314 // Just test for "same value" relation extensibility. | |
| 315 | |
| 316 if (decomposition.base() == other) { | |
| 317 // The direction of the extensibility test is determined by scale and | |
| 318 // offset, but we can not handle all combinations. | |
| 319 int direction = 0; | |
| 320 // Do not accept left shifts greater than 1. | |
| 321 if (decomposition.scale() <= -1) { | |
| 322 if (decomposition.offset() == 0) { | |
| 323 // A positive scale makes values smaller. | |
| 324 direction = -decomposition.scale(); | |
| 325 } else { | |
| 326 // If offset and scale have different signs they both go in the | |
| 327 // same direction, otherwise we cannot handle the combination. | |
| 328 if (decomposition.offset() * decomposition.scale() < 0) { | |
| 329 direction = offset; | |
| 330 } | |
| 331 } | |
| 332 } | |
| 333 | |
| 334 if (relation.ImpliedByEquality(direction)) { | |
| 335 return true; | |
| 336 } | |
| 337 } | |
| 338 } | |
| 198 } | 339 } |
| 199 | 340 |
| 200 // Pass the request to the redefined value. | 341 // Pass the request to the redefined value. |
| 201 HValue* redefined = RedefinedOperand(); | 342 HValue* redefined = RedefinedOperand(); |
| 202 return redefined != NULL && redefined->IsRelationTrue(relation, other, | 343 return redefined != NULL && redefined->IsRelationTrue(relation, other, |
| 203 offset, scale); | 344 offset, scale); |
| 204 } | 345 } |
| 205 | 346 |
| 206 | 347 |
| 207 bool HValue::TryGuaranteeRange(HValue* upper_bound) { | 348 bool HValue::TryGuaranteeRange(HValue* upper_bound, |
| 208 RangeEvaluationContext context = RangeEvaluationContext(this, upper_bound); | 349 HBasicBlock* starting_block_for_hoisting) { |
| 350 if (starting_block_for_hoisting == NULL) { | |
| 351 starting_block_for_hoisting = block(); | |
| 352 } | |
| 353 | |
| 354 bool lower_done, upper_done, lower_result, upper_result; | |
| 355 lower_done = block()->graph()->HasRelationBeenEvaluated( | |
| 356 this, NumericRelation::Ge(), block()->graph()->GetConstant0(), | |
| 357 0, 0, starting_block_for_hoisting, &lower_result); | |
| 358 upper_done = block()->graph()->HasRelationBeenEvaluated( | |
| 359 this, NumericRelation::Lt(), upper_bound, | |
| 360 0, 0, starting_block_for_hoisting, &upper_result); | |
| 361 if (lower_done && upper_done) return lower_result && upper_result; | |
| 362 | |
| 363 RangeEvaluationContext context = RangeEvaluationContext( | |
| 364 this, upper_bound, starting_block_for_hoisting); | |
| 209 TryGuaranteeRangeRecursive(&context); | 365 TryGuaranteeRangeRecursive(&context); |
| 210 bool result = context.is_range_satisfied(); | 366 bool result = context.is_range_satisfied(); |
| 211 if (result) { | 367 if (result) { |
| 212 context.lower_bound_guarantee()->SetResponsibilityForRange(DIRECTION_LOWER); | 368 context.lower_bound_guarantee()->SetResponsibilityForRange(DIRECTION_LOWER); |
| 213 context.upper_bound_guarantee()->SetResponsibilityForRange(DIRECTION_UPPER); | 369 context.upper_bound_guarantee()->SetResponsibilityForRange(DIRECTION_UPPER); |
| 214 } | 370 } |
| 371 | |
| 372 block()->graph()->AddRelationToTable( | |
| 373 this, NumericRelation::Ge(), block()->graph()->GetConstant0(), 0, 0, | |
| 374 starting_block_for_hoisting, context.lower_bound_guarantee() != NULL); | |
| 375 block()->graph()->AddRelationToTable( | |
| 376 this, NumericRelation::Lt(), upper_bound, 0, 0, | |
| 377 starting_block_for_hoisting, context.upper_bound_guarantee() != NULL); | |
| 378 | |
| 215 return result; | 379 return result; |
| 216 } | 380 } |
| 217 | 381 |
| 218 | 382 |
| 219 void HValue::TryGuaranteeRangeRecursive(RangeEvaluationContext* context) { | 383 void HValue::TryGuaranteeRangeRecursive(RangeEvaluationContext* context) { |
| 220 // Check if we already know that this value satisfies the lower bound. | 384 // Check if we already know that this value satisfies the lower bound. |
| 221 if (context->lower_bound_guarantee() == NULL) { | 385 if (context->lower_bound_guarantee() == NULL) { |
| 222 if (IsRelationTrueInternal(NumericRelation::Ge(), context->lower_bound(), | 386 if (IsRelationTrueInternal(NumericRelation::Ge(), context->lower_bound(), |
| 223 context->offset(), context->scale())) { | 387 context->offset(), context->scale())) { |
| 224 context->set_lower_bound_guarantee(this); | 388 context->set_lower_bound_guarantee(this); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 252 context->swap_candidate(&decomposition); | 416 context->swap_candidate(&decomposition); |
| 253 } | 417 } |
| 254 if (context->is_range_satisfied()) return; | 418 if (context->is_range_satisfied()) return; |
| 255 | 419 |
| 256 // Try to modify this to satisfy the constraint. | 420 // Try to modify this to satisfy the constraint. |
| 257 | 421 |
| 258 TryGuaranteeRangeChanging(context); | 422 TryGuaranteeRangeChanging(context); |
| 259 } | 423 } |
| 260 | 424 |
| 261 | 425 |
| 262 RangeEvaluationContext::RangeEvaluationContext(HValue* value, HValue* upper) | 426 RangeEvaluationContext::RangeEvaluationContext(HValue* value, |
| 263 : lower_bound_(upper->block()->graph()->GetConstant0()), | 427 HValue* upper, |
| 428 HBasicBlock* starting_block) | |
| 429 : starting_block_(starting_block), | |
| 430 lower_bound_(upper->block()->graph()->GetConstant0()), | |
| 264 lower_bound_guarantee_(NULL), | 431 lower_bound_guarantee_(NULL), |
| 265 candidate_(value), | 432 candidate_(value), |
| 266 upper_bound_(upper), | 433 upper_bound_(upper), |
| 267 upper_bound_guarantee_(NULL), | 434 upper_bound_guarantee_(NULL), |
| 268 offset_(0), | 435 offset_(0), |
| 269 scale_(0) { | 436 scale_(0) { |
| 270 } | 437 } |
| 271 | 438 |
| 272 | 439 |
| 273 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { | 440 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 } | 1092 } |
| 926 } | 1093 } |
| 927 } | 1094 } |
| 928 #endif | 1095 #endif |
| 929 | 1096 |
| 930 | 1097 |
| 931 HNumericConstraint* HNumericConstraint::AddToGraph( | 1098 HNumericConstraint* HNumericConstraint::AddToGraph( |
| 932 HValue* constrained_value, | 1099 HValue* constrained_value, |
| 933 NumericRelation relation, | 1100 NumericRelation relation, |
| 934 HValue* related_value, | 1101 HValue* related_value, |
| 935 HInstruction* insertion_point) { | 1102 HInstruction* insertion_point, |
| 1103 HBasicBlock* jump_target_when_false) { | |
| 936 if (insertion_point == NULL) { | 1104 if (insertion_point == NULL) { |
| 937 if (constrained_value->IsInstruction()) { | 1105 if (constrained_value->IsInstruction()) { |
| 938 insertion_point = HInstruction::cast(constrained_value); | 1106 insertion_point = HInstruction::cast(constrained_value); |
| 939 } else if (constrained_value->IsPhi()) { | 1107 } else if (constrained_value->IsPhi()) { |
| 940 insertion_point = constrained_value->block()->first(); | 1108 insertion_point = constrained_value->block()->first(); |
| 941 } else { | 1109 } else { |
| 942 UNREACHABLE(); | 1110 UNREACHABLE(); |
| 943 } | 1111 } |
| 944 } | 1112 } |
| 945 HNumericConstraint* result = | 1113 HNumericConstraint* result = |
| 946 new(insertion_point->block()->zone()) HNumericConstraint( | 1114 new(insertion_point->block()->zone()) HNumericConstraint( |
| 947 constrained_value, relation, related_value); | 1115 constrained_value, relation, related_value, jump_target_when_false); |
| 948 result->InsertAfter(insertion_point); | 1116 result->InsertAfter(insertion_point); |
| 949 return result; | 1117 return result; |
| 950 } | 1118 } |
| 951 | 1119 |
| 952 | 1120 |
| 953 void HNumericConstraint::PrintDataTo(StringStream* stream) { | 1121 void HNumericConstraint::PrintDataTo(StringStream* stream) { |
| 954 stream->Add("("); | 1122 stream->Add("("); |
| 955 constrained_value()->PrintNameTo(stream); | 1123 constrained_value()->PrintNameTo(stream); |
| 956 stream->Add(" %s ", relation().Mnemonic()); | 1124 stream->Add(" %s ", relation().Mnemonic()); |
| 957 related_value()->PrintNameTo(stream); | 1125 related_value()->PrintNameTo(stream); |
| 958 stream->Add(")"); | 1126 stream->Add(")"); |
| 959 } | 1127 } |
| 960 | 1128 |
| 961 | 1129 |
| 962 HInductionVariableAnnotation* HInductionVariableAnnotation::AddToGraph( | 1130 HInductionVariableAnnotation* HInductionVariableAnnotation::AddToGraph( |
| 963 HPhi* phi, | 1131 HPhi* phi, |
| 964 NumericRelation relation, | 1132 NumericRelation relation, |
| 965 int operand_index) { | 1133 int operand_index) { |
| 966 HInductionVariableAnnotation* result = | 1134 HInductionVariableAnnotation* result = new(phi->block()->zone()) |
| 967 new(phi->block()->zone()) HInductionVariableAnnotation(phi, relation, | 1135 HInductionVariableAnnotation(phi, relation, operand_index, |
| 968 operand_index); | 1136 phi->block()->zone()); |
| 969 result->InsertAfter(phi->block()->first()); | 1137 result->InsertAfter(phi->block()->first()); |
| 970 return result; | 1138 return result; |
| 971 } | 1139 } |
| 972 | 1140 |
| 973 | 1141 |
| 1142 void HInductionVariableAnnotation::AddHoistedCheck(HBoundsCheck* check) { | |
| 1143 hoisted_checks_.Add(check, block()->zone()); | |
| 1144 } | |
| 1145 | |
| 1146 | |
| 1147 HInductionVariableAnnotation::HInductionVariableAnnotation( | |
| 1148 HPhi* phi, | |
| 1149 NumericRelation relation, | |
| 1150 int operand_index, | |
| 1151 Zone* zone) | |
| 1152 : HUnaryOperation(phi), | |
| 1153 phi_(phi), | |
| 1154 relation_(relation), | |
| 1155 operand_index_(operand_index), | |
| 1156 hoisted_checks_(4, zone) { | |
| 1157 } | |
| 1158 | |
| 1159 | |
| 1160 void HInductionVariableAnnotation::TryGuaranteeRangeChanging( | |
| 1161 RangeEvaluationContext* context) { | |
| 1162 if (relation().IsExtendable(1)) { | |
| 1163 if (context->lower_bound_guarantee() == NULL) return; | |
| 1164 } else { | |
| 1165 return; | |
| 1166 } | |
| 1167 | |
| 1168 for (int i = 0; i < hoisted_checks()->length(); i++) { | |
| 1169 HBoundsCheck* hoisted_check = hoisted_checks()->at(i); | |
| 1170 if (hoisted_check->length()->ActualValue() == | |
| 1171 context->upper_bound()->ActualValue()) { | |
| 1172 context->set_upper_bound_guarantee(hoisted_check); | |
| 1173 return; | |
| 1174 } | |
| 1175 } | |
| 1176 | |
| 1177 HBasicBlock* starting_block = context->starting_block(); | |
| 1178 HLoopInformation* starting_loop = starting_block->current_loop(); | |
| 1179 if (starting_loop == NULL) return; | |
| 1180 HLoopInformation* my_loop = block()->current_loop(); | |
| 1181 if (my_loop == NULL) return; | |
| 1182 if (my_loop->exits_count() > 1 | |
| 1183 && !block()->graph()->use_optimistic_licm()) return; | |
| 1184 if (!my_loop->IsNestedInThisLoop(starting_loop)) return; | |
| 1185 | |
| 1186 for (HValue* candidate = context->candidate(); | |
| 1187 candidate != NULL; | |
| 1188 candidate = candidate->RedefinedOperand()) { | |
| 1189 if (!candidate->IsNumericConstraint()) continue; | |
| 1190 | |
| 1191 HNumericConstraint* constraint = HNumericConstraint::cast(candidate); | |
| 1192 if (!constraint->relation().IsExtendable(-1)) continue; | |
| 1193 HLoopInformation* other_loop = | |
| 1194 constraint->jump_target_when_false()->current_loop(); | |
| 1195 if (other_loop == my_loop) continue; | |
| 1196 | |
| 1197 HBasicBlock* my_header = my_loop->loop_header(); | |
| 1198 HBasicBlock* my_pre_header = my_header->predecessors()->at(0); | |
| 1199 | |
| 1200 HValue* induction_limit = constraint->related_value()->ActualValue(); | |
| 1201 HValue* upper_bound = context->upper_bound()->ActualValue(); | |
| 1202 | |
| 1203 if (induction_limit->block() != my_pre_header && | |
| 1204 !induction_limit->block()->Dominates(my_pre_header)) continue; | |
|
Jakob Kummerow
2013/05/15 12:56:35
another nit: {} please when the condition doesn't
Massi
2013/05/21 12:49:56
Done.
| |
| 1205 if (upper_bound->block() != my_pre_header && | |
| 1206 !upper_bound->block()->Dominates(my_pre_header)) continue; | |
| 1207 | |
| 1208 if (!(induction_limit->representation().Equals( | |
| 1209 upper_bound->representation()) || | |
| 1210 induction_limit->IsInteger32Constant())) { | |
| 1211 continue; | |
| 1212 } | |
| 1213 | |
| 1214 block()->graph()->ClearRelationsTable(); | |
| 1215 | |
| 1216 HBoundsCheck* check = new(block()->zone()) HBoundsCheck( | |
| 1217 induction_limit, upper_bound); | |
| 1218 check->InsertBefore(my_pre_header->end()); | |
| 1219 check->set_allow_equality(true); | |
| 1220 check->UpdateRedefinedUses(); | |
| 1221 AddHoistedCheck(check); | |
| 1222 context->set_upper_bound_guarantee(check); | |
| 1223 return; | |
| 1224 } | |
| 1225 } | |
| 1226 | |
| 1227 | |
| 974 void HInductionVariableAnnotation::PrintDataTo(StringStream* stream) { | 1228 void HInductionVariableAnnotation::PrintDataTo(StringStream* stream) { |
| 975 stream->Add("("); | 1229 stream->Add("("); |
| 976 RedefinedOperand()->PrintNameTo(stream); | 1230 RedefinedOperand()->PrintNameTo(stream); |
| 977 stream->Add(" %s ", relation().Mnemonic()); | 1231 stream->Add(" %s ", relation().Mnemonic()); |
| 978 induction_base()->PrintNameTo(stream); | 1232 induction_base()->PrintNameTo(stream); |
| 979 stream->Add(")"); | 1233 stream->Add(")"); |
| 980 } | 1234 } |
| 981 | 1235 |
| 982 | 1236 |
| 983 void HDummyUse::PrintDataTo(StringStream* stream) { | 1237 void HDummyUse::PrintDataTo(StringStream* stream) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1000 stream->Add("#%d", argument_count()); | 1254 stream->Add("#%d", argument_count()); |
| 1001 } | 1255 } |
| 1002 | 1256 |
| 1003 | 1257 |
| 1004 void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) { | 1258 void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) { |
| 1005 if (context->candidate()->ActualValue() != base()->ActualValue() || | 1259 if (context->candidate()->ActualValue() != base()->ActualValue() || |
| 1006 context->scale() < scale()) { | 1260 context->scale() < scale()) { |
| 1007 return; | 1261 return; |
| 1008 } | 1262 } |
| 1009 | 1263 |
| 1264 // Make so that the strongest possible checks are used as guarantees. | |
| 1265 if (context->lower_bound_guarantee() != NULL && | |
| 1266 context->lower_bound_guarantee() != this) { | |
| 1267 if (context->lower_bound_guarantee()->IsBoundsCheck()) { | |
| 1268 HBoundsCheck* guarantee = HBoundsCheck::cast( | |
| 1269 context->lower_bound_guarantee()); | |
| 1270 if (guarantee->base()->ActualValue() == base()->ActualValue() | |
| 1271 && guarantee->scale() == scale() | |
| 1272 && guarantee->offset() > offset()) { | |
| 1273 context->set_lower_bound_guarantee(this); | |
| 1274 } | |
| 1275 } | |
| 1276 } | |
| 1277 if (context->upper_bound_guarantee() != NULL && | |
| 1278 context->upper_bound_guarantee() != this) { | |
| 1279 if (context->upper_bound_guarantee()->IsBoundsCheck()) { | |
| 1280 HBoundsCheck* guarantee = HBoundsCheck::cast( | |
| 1281 context->upper_bound_guarantee()); | |
| 1282 if (guarantee->base()->ActualValue() == base()->ActualValue() | |
| 1283 && guarantee->scale() == scale() | |
| 1284 && guarantee->offset() < offset()) { | |
| 1285 context->set_upper_bound_guarantee(this); | |
| 1286 } | |
| 1287 } | |
| 1288 } | |
| 1289 | |
| 1010 // TODO(mmassi) | 1290 // TODO(mmassi) |
| 1011 // Instead of checking for "same basic block" we should check for | 1291 // Instead of checking for "same basic block" we should check for |
| 1012 // "dominates and postdominates". | 1292 // "dominates and postdominates". |
| 1013 if (context->upper_bound() == length() && | 1293 if (context->upper_bound() == length() && |
| 1014 context->lower_bound_guarantee() != NULL && | 1294 context->lower_bound_guarantee() != NULL && |
| 1015 context->lower_bound_guarantee() != this && | 1295 context->lower_bound_guarantee() != this && |
| 1016 context->lower_bound_guarantee()->block() != block() && | 1296 context->lower_bound_guarantee()->block() == block() && |
| 1017 offset() < context->offset() && | 1297 offset() < context->offset() && |
| 1018 index_can_increase() && | 1298 index_can_increase() && |
| 1019 context->upper_bound_guarantee() == NULL) { | 1299 context->upper_bound_guarantee() == NULL) { |
| 1020 offset_ = context->offset(); | 1300 offset_ = context->offset(); |
| 1021 SetResponsibilityForRange(DIRECTION_UPPER); | 1301 SetResponsibilityForRange(DIRECTION_UPPER); |
| 1022 context->set_upper_bound_guarantee(this); | 1302 context->set_upper_bound_guarantee(this); |
| 1303 block()->graph()->ClearRelationsTable(); | |
| 1023 } else if (context->upper_bound_guarantee() != NULL && | 1304 } else if (context->upper_bound_guarantee() != NULL && |
| 1024 context->upper_bound_guarantee() != this && | 1305 context->upper_bound_guarantee() != this && |
| 1025 context->upper_bound_guarantee()->block() != block() && | 1306 context->upper_bound_guarantee()->block() == block() && |
| 1026 offset() > context->offset() && | 1307 offset() > context->offset() && |
| 1027 index_can_decrease() && | 1308 index_can_decrease() && |
| 1028 context->lower_bound_guarantee() == NULL) { | 1309 context->lower_bound_guarantee() == NULL) { |
| 1029 offset_ = context->offset(); | 1310 offset_ = context->offset(); |
| 1030 SetResponsibilityForRange(DIRECTION_LOWER); | 1311 SetResponsibilityForRange(DIRECTION_LOWER); |
| 1031 context->set_lower_bound_guarantee(this); | 1312 context->set_lower_bound_guarantee(this); |
| 1313 block()->graph()->ClearRelationsTable(); | |
| 1032 } | 1314 } |
| 1033 } | 1315 } |
| 1034 | 1316 |
| 1035 | 1317 |
| 1036 void HBoundsCheck::ApplyIndexChange() { | 1318 void HBoundsCheck::ApplyIndexChange() { |
| 1037 if (skip_check()) return; | 1319 if (skip_check() || base() == NULL) return; |
| 1038 | 1320 |
| 1039 DecompositionResult decomposition; | 1321 DecompositionResult decomposition; |
| 1040 bool index_is_decomposable = index()->TryDecompose(&decomposition); | 1322 bool index_is_decomposable = index()->TryDecompose(&decomposition); |
| 1041 if (index_is_decomposable) { | 1323 if (index_is_decomposable) { |
| 1042 ASSERT(decomposition.base() == base()); | 1324 ASSERT(decomposition.base() == base()); |
| 1043 if (decomposition.offset() == offset() && | 1325 if (decomposition.offset() == offset() && |
| 1044 decomposition.scale() == scale()) return; | 1326 decomposition.scale() == scale()) return; |
| 1045 } else { | 1327 } else { |
| 1046 return; | 1328 return; |
| 1047 } | 1329 } |
| 1048 | 1330 |
| 1049 ReplaceAllUsesWith(index()); | 1331 ReplaceAllUsesWith(index()); |
| 1050 | 1332 |
| 1051 HValue* current_index = decomposition.base(); | 1333 HValue* current_index = decomposition.base(); |
| 1052 int actual_offset = decomposition.offset() + offset(); | |
| 1053 int actual_scale = decomposition.scale() + scale(); | |
| 1054 | 1334 |
| 1055 if (actual_offset != 0) { | 1335 if (offset() != 0) { |
| 1056 HConstant* add_offset = new(block()->graph()->zone()) HConstant( | 1336 HConstant* add_offset = new(block()->graph()->zone()) HConstant( |
| 1057 actual_offset, index()->representation()); | 1337 offset(), index()->representation()); |
| 1058 add_offset->InsertBefore(this); | 1338 add_offset->InsertBefore(this); |
| 1059 HInstruction* add = HAdd::New(block()->graph()->zone(), | 1339 HInstruction* add = HAdd::New(block()->graph()->zone(), |
| 1060 block()->graph()->GetInvalidContext(), current_index, add_offset); | 1340 block()->graph()->GetInvalidContext(), current_index, add_offset); |
| 1061 add->InsertBefore(this); | 1341 add->InsertBefore(this); |
| 1062 add->AssumeRepresentation(index()->representation()); | 1342 add->AssumeRepresentation(index()->representation()); |
| 1063 current_index = add; | 1343 current_index = add; |
| 1064 } | 1344 } |
| 1065 | 1345 |
| 1066 if (actual_scale != 0) { | 1346 if (scale() != 0) { |
| 1067 HConstant* sar_scale = new(block()->graph()->zone()) HConstant( | 1347 HConstant* sar_scale = new(block()->graph()->zone()) HConstant( |
| 1068 actual_scale, index()->representation()); | 1348 scale(), index()->representation()); |
| 1069 sar_scale->InsertBefore(this); | 1349 sar_scale->InsertBefore(this); |
| 1070 HInstruction* sar = HSar::New(block()->graph()->zone(), | 1350 HInstruction* sar = HSar::New(block()->graph()->zone(), |
| 1071 block()->graph()->GetInvalidContext(), current_index, sar_scale); | 1351 block()->graph()->GetInvalidContext(), current_index, sar_scale); |
| 1072 sar->InsertBefore(this); | 1352 sar->InsertBefore(this); |
| 1073 sar->AssumeRepresentation(index()->representation()); | 1353 sar->AssumeRepresentation(index()->representation()); |
| 1074 current_index = sar; | 1354 current_index = sar; |
| 1075 } | 1355 } |
| 1076 | 1356 |
| 1077 SetOperandAt(0, current_index); | 1357 SetOperandAt(0, current_index); |
| 1078 | 1358 |
| 1079 base_ = NULL; | 1359 base_ = NULL; |
| 1080 offset_ = 0; | 1360 offset_ = 0; |
| 1081 scale_ = 0; | 1361 scale_ = 0; |
| 1082 responsibility_direction_ = DIRECTION_NONE; | 1362 responsibility_direction_ = DIRECTION_NONE; |
| 1083 } | 1363 } |
| 1084 | 1364 |
| 1085 | 1365 |
| 1086 void HBoundsCheck::AddInformativeDefinitions() { | 1366 void HBoundsCheck::AddInformativeDefinitions() { |
| 1087 // TODO(mmassi): Executing this code during AddInformativeDefinitions | 1367 if (DetectCompoundIndex()) { |
| 1088 // is a hack. Move it to some other HPhase. | 1368 HBoundsCheckBaseIndexInformation* base_index_info = |
| 1089 if (FLAG_array_bounds_checks_elimination) { | 1369 new(block()->graph()->zone()) |
| 1090 if (index()->TryGuaranteeRange(length())) { | 1370 HBoundsCheckBaseIndexInformation(this); |
| 1091 set_skip_check(true); | 1371 base_index_info->InsertAfter(this); |
| 1092 } | |
| 1093 if (DetectCompoundIndex()) { | |
| 1094 HBoundsCheckBaseIndexInformation* base_index_info = | |
| 1095 new(block()->graph()->zone()) | |
| 1096 HBoundsCheckBaseIndexInformation(this); | |
| 1097 base_index_info->InsertAfter(this); | |
| 1098 } | |
| 1099 } | 1372 } |
| 1100 } | 1373 } |
| 1101 | 1374 |
| 1102 | 1375 |
| 1103 bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation, | 1376 bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation, |
| 1104 HValue* related_value, | 1377 HValue* related_value, |
| 1105 int offset, | 1378 int offset, |
| 1106 int scale) { | 1379 int scale) { |
| 1107 if (related_value == length()) { | 1380 if (related_value == length()) { |
| 1108 // A HBoundsCheck is smaller than the length it compared against. | 1381 // A HBoundsCheck is smaller than the length it compared against. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1156 } | 1429 } |
| 1157 UpdateRepresentation(r, h_infer, "boundscheck"); | 1430 UpdateRepresentation(r, h_infer, "boundscheck"); |
| 1158 } | 1431 } |
| 1159 | 1432 |
| 1160 | 1433 |
| 1161 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal( | 1434 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal( |
| 1162 NumericRelation relation, | 1435 NumericRelation relation, |
| 1163 HValue* related_value, | 1436 HValue* related_value, |
| 1164 int offset, | 1437 int offset, |
| 1165 int scale) { | 1438 int scale) { |
| 1439 if (bounds_check() == NULL) return false; | |
| 1440 | |
| 1166 if (related_value == bounds_check()->length()) { | 1441 if (related_value == bounds_check()->length()) { |
| 1167 return NumericRelation::Lt().CompoundImplies( | 1442 return NumericRelation::Lt().CompoundImplies( |
| 1168 relation, | 1443 relation, |
| 1169 bounds_check()->offset(), bounds_check()->scale(), offset, scale); | 1444 bounds_check()->offset(), bounds_check()->scale(), offset, scale); |
| 1170 } else if (related_value == block()->graph()->GetConstant0()) { | 1445 } else if (related_value == block()->graph()->GetConstant0()) { |
| 1171 return NumericRelation::Ge().CompoundImplies( | 1446 return NumericRelation::Ge().CompoundImplies( |
| 1172 relation, | 1447 relation, |
| 1173 bounds_check()->offset(), bounds_check()->scale(), offset, scale); | 1448 bounds_check()->offset(), bounds_check()->scale(), offset, scale); |
| 1174 } else { | 1449 } else { |
| 1175 return false; | 1450 return false; |
| 1176 } | 1451 } |
| 1177 } | 1452 } |
| 1178 | 1453 |
| 1179 | 1454 |
| 1180 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) { | 1455 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) { |
| 1181 stream->Add("base: "); | 1456 stream->Add("base: "); |
| 1182 base_index()->PrintNameTo(stream); | 1457 base_index()->PrintNameTo(stream); |
| 1183 stream->Add(", check: "); | 1458 stream->Add(", check: "); |
| 1184 base_index()->PrintNameTo(stream); | 1459 if (bounds_check() != NULL) { |
| 1460 bounds_check()->PrintNameTo(stream); | |
| 1461 } else { | |
| 1462 stream->Add("DISCONNECTED "); | |
| 1463 OperandAt(1)->PrintNameTo(stream); | |
| 1464 } | |
| 1185 } | 1465 } |
| 1186 | 1466 |
| 1187 | 1467 |
| 1188 void HCallConstantFunction::PrintDataTo(StringStream* stream) { | 1468 void HCallConstantFunction::PrintDataTo(StringStream* stream) { |
| 1189 if (IsApplyFunction()) { | 1469 if (IsApplyFunction()) { |
| 1190 stream->Add("optimized apply "); | 1470 stream->Add("optimized apply "); |
| 1191 } else { | 1471 } else { |
| 1192 stream->Add("%o ", function()->shared()->DebugName()); | 1472 stream->Add("%o ", function()->shared()->DebugName()); |
| 1193 } | 1473 } |
| 1194 stream->Add("#%d", argument_count()); | 1474 stream->Add("#%d", argument_count()); |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1805 ClearFlag(HValue::kCanBeDivByZero); | 2085 ClearFlag(HValue::kCanBeDivByZero); |
| 1806 } | 2086 } |
| 1807 return result; | 2087 return result; |
| 1808 } else { | 2088 } else { |
| 1809 return HValue::InferRange(zone); | 2089 return HValue::InferRange(zone); |
| 1810 } | 2090 } |
| 1811 } | 2091 } |
| 1812 | 2092 |
| 1813 | 2093 |
| 1814 void HPhi::AddInformativeDefinitions() { | 2094 void HPhi::AddInformativeDefinitions() { |
| 1815 if (OperandCount() == 2) { | 2095 HLoopInformation* my_loop = block()->current_loop(); |
| 2096 | |
| 2097 if (OperandCount() == 2 && my_loop != NULL) { | |
| 1816 // If one of the operands is an OSR block give up (this cannot be an | 2098 // If one of the operands is an OSR block give up (this cannot be an |
| 1817 // induction variable). | 2099 // induction variable). |
| 1818 if (OperandAt(0)->block()->is_osr_entry() || | 2100 if (OperandAt(0)->block()->is_osr_entry() || |
| 1819 OperandAt(1)->block()->is_osr_entry()) return; | 2101 OperandAt(1)->block()->is_osr_entry()) return; |
| 1820 | 2102 |
| 1821 for (int operand_index = 0; operand_index < 2; operand_index++) { | 2103 for (int operand_index = 0; operand_index < 2; operand_index++) { |
| 1822 int other_operand_index = (operand_index + 1) % 2; | 2104 int other_operand_index = (operand_index + 1) % 2; |
| 1823 | 2105 |
| 2106 HValue* induction_base_cantidate = OperandAt(other_operand_index); | |
|
Jakob Kummerow
2013/05/15 12:56:35
nit: s/cantidate/candidate/
Massi
2013/05/21 12:49:56
Done.
| |
| 2107 HLoopInformation* base_block_loop = | |
| 2108 induction_base_cantidate->block()->current_loop(); | |
| 2109 if (base_block_loop != NULL && | |
| 2110 (base_block_loop == my_loop || | |
| 2111 base_block_loop->IsNestedInThisLoop(my_loop))) continue; | |
| 2112 | |
| 1824 static NumericRelation relations[] = { | 2113 static NumericRelation relations[] = { |
| 1825 NumericRelation::Ge(), | 2114 NumericRelation::Gt(), |
| 1826 NumericRelation::Le() | 2115 NumericRelation::Lt() |
| 1827 }; | 2116 }; |
| 1828 | 2117 |
| 1829 // Check if this phi is an induction variable. If, e.g., we know that | 2118 // Check if this phi is an induction variable. If, e.g., we know that |
| 1830 // its first input is greater than the phi itself, then that must be | 2119 // its first input is greater than the phi itself, then that must be |
| 1831 // the back edge, and the phi is always greater than its second input. | 2120 // the back edge, and the phi is always greater than its second input. |
| 1832 for (int relation_index = 0; relation_index < 2; relation_index++) { | 2121 for (int relation_index = 0; relation_index < 2; relation_index++) { |
| 1833 if (OperandAt(operand_index)->IsRelationTrue(relations[relation_index], | 2122 if (OperandAt(operand_index)->IsRelationTrue(relations[relation_index], |
| 1834 this)) { | 2123 this)) { |
| 1835 HInductionVariableAnnotation::AddToGraph(this, | 2124 HInductionVariableAnnotation::AddToGraph(this, |
| 1836 relations[relation_index], | 2125 relations[relation_index], |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2337 stream->Add(Token::Name(token())); | 2626 stream->Add(Token::Name(token())); |
| 2338 stream->Add(" "); | 2627 stream->Add(" "); |
| 2339 HControlInstruction::PrintDataTo(stream); | 2628 HControlInstruction::PrintDataTo(stream); |
| 2340 } | 2629 } |
| 2341 | 2630 |
| 2342 | 2631 |
| 2343 void HCompareIDAndBranch::AddInformativeDefinitions() { | 2632 void HCompareIDAndBranch::AddInformativeDefinitions() { |
| 2344 NumericRelation r = NumericRelation::FromToken(token()); | 2633 NumericRelation r = NumericRelation::FromToken(token()); |
| 2345 if (r.IsNone()) return; | 2634 if (r.IsNone()) return; |
| 2346 | 2635 |
| 2347 HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first()); | |
| 2348 HNumericConstraint::AddToGraph( | 2636 HNumericConstraint::AddToGraph( |
| 2349 left(), r.Negated(), right(), SuccessorAt(1)->first()); | 2637 left(), r, right(), SuccessorAt(0)->first(), SuccessorAt(1)); |
| 2638 HNumericConstraint::AddToGraph( | |
| 2639 left(), r.Negated(), right(), SuccessorAt(1)->first(), SuccessorAt(0)); | |
| 2350 } | 2640 } |
| 2351 | 2641 |
| 2352 | 2642 |
| 2353 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { | 2643 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { |
| 2354 stream->Add(Token::Name(token())); | 2644 stream->Add(Token::Name(token())); |
| 2355 stream->Add(" "); | 2645 stream->Add(" "); |
| 2356 left()->PrintNameTo(stream); | 2646 left()->PrintNameTo(stream); |
| 2357 stream->Add(" "); | 2647 stream->Add(" "); |
| 2358 right()->PrintNameTo(stream); | 2648 right()->PrintNameTo(stream); |
| 2359 HControlInstruction::PrintDataTo(stream); | 2649 HControlInstruction::PrintDataTo(stream); |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3031 visited->Add(id()); | 3321 visited->Add(id()); |
| 3032 // Propagate to the left argument. If the left argument cannot be -0, then | 3322 // Propagate to the left argument. If the left argument cannot be -0, then |
| 3033 // the result of the sub operation cannot be either. | 3323 // the result of the sub operation cannot be either. |
| 3034 if (range() == NULL || range()->CanBeMinusZero()) { | 3324 if (range() == NULL || range()->CanBeMinusZero()) { |
| 3035 return left(); | 3325 return left(); |
| 3036 } | 3326 } |
| 3037 return NULL; | 3327 return NULL; |
| 3038 } | 3328 } |
| 3039 | 3329 |
| 3040 | 3330 |
| 3331 bool HAdd::IsRelationTrueInternal(NumericRelation relation, | |
| 3332 HValue* other, | |
| 3333 int offset, | |
| 3334 int scale) { | |
| 3335 if (offset != 0 || scale != 0) return false; | |
| 3336 | |
| 3337 // We look for a pattern like "x + delta rel x", where we should return | |
| 3338 // true if "delta >= 0 && rel.IsExtendable(1)" or | |
| 3339 // "delta <= 0 && rel.IsExtendable(-1)". | |
| 3340 HValue* delta = NULL; | |
| 3341 if (left()->ActualValue() == other->ActualValue()) { | |
| 3342 delta = right(); | |
| 3343 } else if (right()->ActualValue() == other->ActualValue()) { | |
| 3344 delta = left(); | |
| 3345 } else { | |
| 3346 return false; | |
| 3347 } | |
| 3348 | |
| 3349 if (relation.IsExtendable(1) && | |
| 3350 delta->IsRelationTrue(NumericRelation::Ge(), | |
| 3351 block()->graph()->GetConstant0())) { | |
| 3352 return true; | |
| 3353 } | |
| 3354 | |
| 3355 if (relation.IsExtendable(-1) && | |
| 3356 delta->IsRelationTrue(NumericRelation::Le(), | |
| 3357 block()->graph()->GetConstant0())) { | |
| 3358 return true; | |
| 3359 } | |
| 3360 | |
| 3361 return false; | |
| 3362 } | |
| 3363 | |
| 3364 | |
| 3041 bool HStoreKeyed::NeedsCanonicalization() { | 3365 bool HStoreKeyed::NeedsCanonicalization() { |
| 3042 // If value is an integer or smi or comes from the result of a keyed load or | 3366 // If value is an integer or smi or comes from the result of a keyed load or |
| 3043 // constant then it is either be a non-hole value or in the case of a constant | 3367 // constant then it is either be a non-hole value or in the case of a constant |
| 3044 // the hole is only being stored explicitly: no need for canonicalization. | 3368 // the hole is only being stored explicitly: no need for canonicalization. |
| 3045 // | 3369 // |
| 3046 // The exception to that is keyed loads from external float or double arrays: | 3370 // The exception to that is keyed loads from external float or double arrays: |
| 3047 // these can load arbitrary representation of NaN. | 3371 // these can load arbitrary representation of NaN. |
| 3048 | 3372 |
| 3049 if (value()->IsConstant()) { | 3373 if (value()->IsConstant()) { |
| 3050 return false; | 3374 return false; |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3533 | 3857 |
| 3534 | 3858 |
| 3535 void HCheckFunction::Verify() { | 3859 void HCheckFunction::Verify() { |
| 3536 HInstruction::Verify(); | 3860 HInstruction::Verify(); |
| 3537 ASSERT(HasNoUses()); | 3861 ASSERT(HasNoUses()); |
| 3538 } | 3862 } |
| 3539 | 3863 |
| 3540 #endif | 3864 #endif |
| 3541 | 3865 |
| 3542 } } // namespace v8::internal | 3866 } } // namespace v8::internal |
| OLD | NEW |