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

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

Issue 14046017: Abcd for performance check. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes and speedups in induction variable detection. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698