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

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: Rebased on bleeding edge. 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
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 namespace internal { 47 namespace internal {
48 48
49 #define DEFINE_COMPILE(type) \ 49 #define DEFINE_COMPILE(type) \
50 LInstruction* H##type::CompileToLithium(LChunkBuilder* builder) { \ 50 LInstruction* H##type::CompileToLithium(LChunkBuilder* builder) { \
51 return builder->Do##type(this); \ 51 return builder->Do##type(this); \
52 } 52 }
53 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) 53 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE)
54 #undef DEFINE_COMPILE 54 #undef DEFINE_COMPILE
55 55
56 56
57 bool NumericRelationTable::IsInTable(int value_id,
58 NumericRelation relation,
59 int other_value_id,
60 int offset,
61 int scale,
62 int block_id,
63 bool* result) {
64 NumericRelationTableElement element(value_id, relation, other_value_id,
65 offset, scale, block_id, false);
66 int index = FindInsertionPoint(element, result);
67 return index < 0;
68 }
69
70
71 void NumericRelationTable::AddToTable(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, result);
80 bool res;
81 int index = FindInsertionPoint(element, &res);
82 if (index >= 0) {
83 Insert(element, index);
84 }
85 }
86
87
88 void NumericRelationTable::Clear() {
89 table_.Clear();
90 }
91
92
93 int NumericRelationTable::FindInsertionPoint(
94 const NumericRelationTableElement& element,
95 bool* result) {
96 int lower = 0;
97 int upper = table_.length();
98 if (upper == 0) return 0;
99
100 while (true) {
101 int middle = (lower + upper) >> 1;
102
103 int comparison = element.Compare(table_.at(middle));
104 if (comparison > 0) {
105 if (lower == middle) {
106 if (upper < table_.length()) {
107 if (element.Compare(table_.at(upper)) == 0) {
108 *result = table_.at(upper).result();
109 return -1;
110 } else {
111 return upper;
112 }
113 } else {
114 return upper;
115 }
116 } else {
117 lower = middle;
118 }
119 } else if (comparison < 0) {
120 if (upper == middle) {
121 return middle;
122 } else {
123 upper = middle;
124 }
125 } else {
126 *result = table_.at(middle).result();
127 return -1;
128 }
129 }
130 }
131
132
133 void NumericRelationTable::Insert(const NumericRelationTableElement& element,
134 int index) {
135 table_.InsertAt(index, element, zone_);
136 }
137
138
57 int HValue::LoopWeight() const { 139 int HValue::LoopWeight() const {
58 const int w = FLAG_loop_weight; 140 const int w = FLAG_loop_weight;
59 static const int weights[] = { 1, w, w*w, w*w*w, w*w*w*w }; 141 static const int weights[] = { 1, w, w*w, w*w*w, w*w*w*w };
60 return weights[Min(block()->LoopNestingDepth(), 142 return weights[Min(block()->LoopNestingDepth(),
61 static_cast<int>(ARRAY_SIZE(weights)-1))]; 143 static_cast<int>(ARRAY_SIZE(weights)-1))];
62 } 144 }
63 145
64 146
65 Isolate* HValue::isolate() const { 147 Isolate* HValue::isolate() const {
66 ASSERT(block() != NULL); 148 ASSERT(block() != NULL);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 void HValue::AddDependantsToWorklist(HInferRepresentation* h_infer) { 228 void HValue::AddDependantsToWorklist(HInferRepresentation* h_infer) {
147 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 229 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
148 h_infer->AddToWorklist(it.value()); 230 h_infer->AddToWorklist(it.value());
149 } 231 }
150 for (int i = 0; i < OperandCount(); ++i) { 232 for (int i = 0; i < OperandCount(); ++i) {
151 h_infer->AddToWorklist(OperandAt(i)); 233 h_infer->AddToWorklist(OperandAt(i));
152 } 234 }
153 } 235 }
154 236
155 237
156 // This method is recursive but it is guaranteed to terminate because
157 // RedefinedOperand() always dominates "this".
158 bool HValue::IsRelationTrue(NumericRelation relation, 238 bool HValue::IsRelationTrue(NumericRelation relation,
159 HValue* other, 239 HValue* other,
160 int offset, 240 int offset,
161 int scale) { 241 int scale) {
162 if (this == other) { 242 bool result;
163 return scale == 0 && relation.IsExtendable(offset); 243 if (block()->graph()->HasRelationBeenEvaluated(
244 this, relation, other, offset, scale, block(), &result)) {
245 return result;
246 }
247
248 result = EvaluateRelationRecursively(relation, other, offset, scale);
249
250 block()->graph()->AddRelationToTable(
251 this, relation, other, offset, scale, block(), result);
252 return result;
253 }
254
255
256 // This method is a recursive graph walk but it is guaranteed to terminate
257 // because RedefinedOperand() always dominates "this" and phis will check
258 // the "kNumericConstraintEvaluationInProgress" flag and never re-evaluate
259 // themselves.
260 bool HValue::EvaluateRelationRecursively(NumericRelation relation,
261 HValue* other,
262 int offset,
263 int scale) {
264 if (ActualValue() == other->ActualValue()) {
265 return scale == 0 && relation.ImpliedByEquality(offset);
164 } 266 }
165 267
166 // Test the direct relation. 268 // Test the direct relation.
167 if (IsRelationTrueInternal(relation, other, offset, scale)) return true; 269 if (IsRelationTrueInternal(relation, other, offset, scale)) return true;
168 270
169 // If scale is 0 try the reversed relation. 271 // If scale is 0 try the reversed relation.
170 if (scale == 0 && 272 if (scale == 0 &&
171 // TODO(mmassi): do we need the full, recursive IsRelationTrue? 273 // TODO(mmassi): do we need the full, recursive IsRelationTrue?
172 other->IsRelationTrueInternal(relation.Reversed(), this, -offset)) { 274 other->IsRelationTrueInternal(relation.Reversed(), this, -offset)) {
173 return true; 275 return true;
174 } 276 }
175 277
176 // Try decomposition (but do not accept scaled compounds). 278 // Try decomposition, but only if we are not scaled.
177 DecompositionResult decomposition; 279 DecompositionResult decomposition;
178 if (TryDecompose(&decomposition) && 280 if (scale == 0 && TryDecompose(&decomposition)) {
179 decomposition.scale() == 0 && 281 // Check if the compound is scaled.
180 decomposition.base()->IsRelationTrue(relation, other, 282 if (decomposition.scale() == 0) {
181 offset + decomposition.offset(), 283 // Non-scaled compounds can be handled normally.
182 scale)) { 284 if (decomposition.base()->IsRelationTrue(
183 return true; 285 relation, other, offset + decomposition.offset(), scale)) {
286 return true;
287 }
288 } else if (decomposition.offset() == 0 && offset == 0) {
289 // We only have a scale value which means that we can apply chaining
290 // using relation extensibility: negative scales grow values (positive
291 // direction), positive scales make them smaller (negative direction).
292 // As a concrete example: "(x << 1) <= 0" <== "x <= 0".
293 int direction = -decomposition.scale();
294 if (relation.IsExtendable(direction) &&
295 decomposition.base()->IsRelationTrue(relation, other, 0, 0)) {
296 return true;
297 }
298
299 } else {
300 // Just test for "same value" relation extensibility.
301
302 if (decomposition.base() == other) {
303 // The direction of the extensibility test is determined by scale and
304 // offset, but we can not handle all combinations.
305 int direction = 0;
306 // Do not accept left shifts greater than 1.
307 if (decomposition.scale() <= -1) {
308 if (decomposition.offset() == 0) {
309 // A positive scale makes values smaller.
310 direction = -decomposition.scale();
311 } else {
312 // If offset and scale have different signs they both go in the
313 // same direction, otherwise we cannot handle the combination.
314 if (decomposition.offset() * decomposition.scale() < 0) {
315 direction = offset;
316 }
317 }
318 }
319
320 if (relation.ImpliedByEquality(direction)) {
321 return true;
322 }
323 }
324 }
184 } 325 }
185 326
186 // Pass the request to the redefined value. 327 // Pass the request to the redefined value.
187 HValue* redefined = RedefinedOperand(); 328 HValue* redefined = RedefinedOperand();
188 return redefined != NULL && redefined->IsRelationTrue(relation, other, 329 return redefined != NULL && redefined->IsRelationTrue(relation, other,
189 offset, scale); 330 offset, scale);
190 } 331 }
191 332
192 333
193 bool HValue::TryGuaranteeRange(HValue* upper_bound) { 334 bool HValue::TryGuaranteeRange(HValue* upper_bound,
194 RangeEvaluationContext context = RangeEvaluationContext(this, upper_bound); 335 HBasicBlock* starting_block_for_hoisting) {
336 if (starting_block_for_hoisting == NULL) {
337 starting_block_for_hoisting = block();
338 }
339
340 bool lower_done, upper_done, lower_result, upper_result;
341 lower_done = block()->graph()->HasRelationBeenEvaluated(
342 this, NumericRelation::Ge(), block()->graph()->GetConstant0(),
343 0, 0, starting_block_for_hoisting, &lower_result);
344 upper_done = block()->graph()->HasRelationBeenEvaluated(
345 this, NumericRelation::Lt(), upper_bound,
346 0, 0, starting_block_for_hoisting, &upper_result);
347 if (lower_done && upper_done) return lower_result && upper_result;
348
349 RangeEvaluationContext context = RangeEvaluationContext(
350 this, upper_bound, starting_block_for_hoisting);
195 TryGuaranteeRangeRecursive(&context); 351 TryGuaranteeRangeRecursive(&context);
196 bool result = context.is_range_satisfied(); 352 bool result = context.is_range_satisfied();
197 if (result) { 353 if (result) {
198 context.lower_bound_guarantee()->SetResponsibilityForRange(DIRECTION_LOWER); 354 context.lower_bound_guarantee()->SetResponsibilityForRange(DIRECTION_LOWER);
199 context.upper_bound_guarantee()->SetResponsibilityForRange(DIRECTION_UPPER); 355 context.upper_bound_guarantee()->SetResponsibilityForRange(DIRECTION_UPPER);
200 } 356 }
357
358 block()->graph()->AddRelationToTable(
359 this, NumericRelation::Ge(), block()->graph()->GetConstant0(), 0, 0,
360 starting_block_for_hoisting, context.lower_bound_guarantee() != NULL);
361 block()->graph()->AddRelationToTable(
362 this, NumericRelation::Lt(), upper_bound, 0, 0,
363 starting_block_for_hoisting, context.upper_bound_guarantee() != NULL);
364
201 return result; 365 return result;
202 } 366 }
203 367
204 368
205 void HValue::TryGuaranteeRangeRecursive(RangeEvaluationContext* context) { 369 void HValue::TryGuaranteeRangeRecursive(RangeEvaluationContext* context) {
206 // Check if we already know that this value satisfies the lower bound. 370 // Check if we already know that this value satisfies the lower bound.
207 if (context->lower_bound_guarantee() == NULL) { 371 if (context->lower_bound_guarantee() == NULL) {
208 if (IsRelationTrueInternal(NumericRelation::Ge(), context->lower_bound(), 372 if (IsRelationTrueInternal(NumericRelation::Ge(), context->lower_bound(),
209 context->offset(), context->scale())) { 373 context->offset(), context->scale())) {
210 context->set_lower_bound_guarantee(this); 374 context->set_lower_bound_guarantee(this);
(...skipping 27 matching lines...) Expand all
238 context->swap_candidate(&decomposition); 402 context->swap_candidate(&decomposition);
239 } 403 }
240 if (context->is_range_satisfied()) return; 404 if (context->is_range_satisfied()) return;
241 405
242 // Try to modify this to satisfy the constraint. 406 // Try to modify this to satisfy the constraint.
243 407
244 TryGuaranteeRangeChanging(context); 408 TryGuaranteeRangeChanging(context);
245 } 409 }
246 410
247 411
248 RangeEvaluationContext::RangeEvaluationContext(HValue* value, HValue* upper) 412 RangeEvaluationContext::RangeEvaluationContext(HValue* value,
249 : lower_bound_(upper->block()->graph()->GetConstant0()), 413 HValue* upper,
414 HBasicBlock* starting_block)
415 : starting_block_(starting_block),
416 lower_bound_(upper->block()->graph()->GetConstant0()),
250 lower_bound_guarantee_(NULL), 417 lower_bound_guarantee_(NULL),
251 candidate_(value), 418 candidate_(value),
252 upper_bound_(upper), 419 upper_bound_(upper),
253 upper_bound_guarantee_(NULL), 420 upper_bound_guarantee_(NULL),
254 offset_(0), 421 offset_(0),
255 scale_(0) { 422 scale_(0) {
256 } 423 }
257 424
258 425
259 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { 426 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) {
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 } 1094 }
928 } 1095 }
929 } 1096 }
930 #endif 1097 #endif
931 1098
932 1099
933 HNumericConstraint* HNumericConstraint::AddToGraph( 1100 HNumericConstraint* HNumericConstraint::AddToGraph(
934 HValue* constrained_value, 1101 HValue* constrained_value,
935 NumericRelation relation, 1102 NumericRelation relation,
936 HValue* related_value, 1103 HValue* related_value,
937 HInstruction* insertion_point) { 1104 HInstruction* insertion_point,
1105 HBasicBlock* jump_target_when_false) {
938 if (insertion_point == NULL) { 1106 if (insertion_point == NULL) {
939 if (constrained_value->IsInstruction()) { 1107 if (constrained_value->IsInstruction()) {
940 insertion_point = HInstruction::cast(constrained_value); 1108 insertion_point = HInstruction::cast(constrained_value);
941 } else if (constrained_value->IsPhi()) { 1109 } else if (constrained_value->IsPhi()) {
942 insertion_point = constrained_value->block()->first(); 1110 insertion_point = constrained_value->block()->first();
943 } else { 1111 } else {
944 UNREACHABLE(); 1112 UNREACHABLE();
945 } 1113 }
946 } 1114 }
947 HNumericConstraint* result = 1115 HNumericConstraint* result =
948 new(insertion_point->block()->zone()) HNumericConstraint( 1116 new(insertion_point->block()->zone()) HNumericConstraint(
949 constrained_value, relation, related_value); 1117 constrained_value, relation, related_value, jump_target_when_false);
950 result->InsertAfter(insertion_point); 1118 result->InsertAfter(insertion_point);
951 return result; 1119 return result;
952 } 1120 }
953 1121
954 1122
955 void HNumericConstraint::PrintDataTo(StringStream* stream) { 1123 void HNumericConstraint::PrintDataTo(StringStream* stream) {
956 stream->Add("("); 1124 stream->Add("(");
957 constrained_value()->PrintNameTo(stream); 1125 constrained_value()->PrintNameTo(stream);
958 stream->Add(" %s ", relation().Mnemonic()); 1126 stream->Add(" %s ", relation().Mnemonic());
959 related_value()->PrintNameTo(stream); 1127 related_value()->PrintNameTo(stream);
960 stream->Add(")"); 1128 stream->Add(")");
961 } 1129 }
962 1130
963 1131
964 HInductionVariableAnnotation* HInductionVariableAnnotation::AddToGraph( 1132 HInductionVariableAnnotation* HInductionVariableAnnotation::AddToGraph(
965 HPhi* phi, 1133 HPhi* phi,
966 NumericRelation relation, 1134 NumericRelation relation,
967 int operand_index) { 1135 int operand_index) {
968 HInductionVariableAnnotation* result = 1136 HInductionVariableAnnotation* result = new(phi->block()->zone())
969 new(phi->block()->zone()) HInductionVariableAnnotation(phi, relation, 1137 HInductionVariableAnnotation(phi, relation, operand_index,
970 operand_index); 1138 phi->block()->zone());
971 result->InsertAfter(phi->block()->first()); 1139 result->InsertAfter(phi->block()->first());
972 return result; 1140 return result;
973 } 1141 }
974 1142
975 1143
1144 void HInductionVariableAnnotation::AddHoistedCheck(HBoundsCheck* check) {
1145 hoisted_checks_.Add(check, block()->zone());
1146 }
1147
1148
1149 HInductionVariableAnnotation::HInductionVariableAnnotation(
1150 HPhi* phi,
1151 NumericRelation relation,
1152 int operand_index,
1153 Zone* zone)
1154 : HUnaryOperation(phi),
1155 phi_(phi),
1156 relation_(relation),
1157 operand_index_(operand_index),
1158 hoisted_checks_(4, zone) {
1159 }
1160
1161
1162 void HInductionVariableAnnotation::TryGuaranteeRangeChanging(
1163 RangeEvaluationContext* context) {
1164 if (relation().IsExtendable(1)) {
1165 if (context->lower_bound_guarantee() == NULL) return;
1166 } else {
1167 return;
1168 }
1169
1170 for (int i = 0; i < hoisted_checks()->length(); i++) {
1171 HBoundsCheck* hoisted_check = hoisted_checks()->at(i);
1172 if (hoisted_check->length()->ActualValue() ==
1173 context->upper_bound()->ActualValue()) {
1174 context->set_upper_bound_guarantee(hoisted_check);
1175 return;
1176 }
1177 }
1178
1179 HBasicBlock* starting_block = context->starting_block();
1180 HLoopInformation* starting_loop = starting_block->current_loop();
1181 if (starting_loop == NULL) return;
1182 HLoopInformation* my_loop = block()->current_loop();
1183 if (my_loop == NULL) return;
1184 if (my_loop->exits_count() > 1
1185 && !block()->graph()->use_optimistic_licm()) return;
1186 if (!my_loop->IsNestedInThisLoop(starting_loop)) return;
1187
1188 for (HValue* candidate = context->candidate();
1189 candidate != NULL;
1190 candidate = candidate->RedefinedOperand()) {
1191 if (!candidate->IsNumericConstraint()) continue;
1192
1193 HNumericConstraint* constraint = HNumericConstraint::cast(candidate);
1194 if (!constraint->relation().IsExtendable(-1)) continue;
1195 HLoopInformation* other_loop =
1196 constraint->jump_target_when_false()->current_loop();
1197 if (other_loop == my_loop) continue;
1198
1199 HBasicBlock* my_header = my_loop->loop_header();
1200 HBasicBlock* my_pre_header = my_header->predecessors()->at(0);
1201
1202 HValue* induction_limit = constraint->related_value()->ActualValue();
1203 HValue* upper_bound = context->upper_bound()->ActualValue();
1204
1205 if (induction_limit->block() != my_pre_header &&
1206 !induction_limit->block()->Dominates(my_pre_header)) {
1207 continue;
1208 }
1209 if (upper_bound->block() != my_pre_header &&
1210 !upper_bound->block()->Dominates(my_pre_header)) {
1211 continue;
1212 }
1213
1214 if (!(induction_limit->representation().Equals(
1215 upper_bound->representation()) ||
1216 induction_limit->IsInteger32Constant())) {
1217 continue;
1218 }
1219
1220 block()->graph()->ClearRelationsTable();
1221
1222 HBoundsCheck* check = new(block()->zone()) HBoundsCheck(
1223 induction_limit, upper_bound);
1224 check->InsertBefore(my_pre_header->end());
1225 check->set_allow_equality(true);
1226 check->UpdateRedefinedUses();
1227 AddHoistedCheck(check);
1228 context->set_upper_bound_guarantee(check);
1229 return;
1230 }
1231 }
1232
1233
976 void HInductionVariableAnnotation::PrintDataTo(StringStream* stream) { 1234 void HInductionVariableAnnotation::PrintDataTo(StringStream* stream) {
977 stream->Add("("); 1235 stream->Add("(");
978 RedefinedOperand()->PrintNameTo(stream); 1236 RedefinedOperand()->PrintNameTo(stream);
979 stream->Add(" %s ", relation().Mnemonic()); 1237 stream->Add(" %s ", relation().Mnemonic());
980 induction_base()->PrintNameTo(stream); 1238 induction_base()->PrintNameTo(stream);
981 stream->Add(")"); 1239 stream->Add(")");
982 } 1240 }
983 1241
984 1242
985 void HDummyUse::PrintDataTo(StringStream* stream) { 1243 void HDummyUse::PrintDataTo(StringStream* stream) {
(...skipping 16 matching lines...) Expand all
1002 stream->Add("#%d", argument_count()); 1260 stream->Add("#%d", argument_count());
1003 } 1261 }
1004 1262
1005 1263
1006 void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) { 1264 void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
1007 if (context->candidate()->ActualValue() != base()->ActualValue() || 1265 if (context->candidate()->ActualValue() != base()->ActualValue() ||
1008 context->scale() < scale()) { 1266 context->scale() < scale()) {
1009 return; 1267 return;
1010 } 1268 }
1011 1269
1270 // Make so that the strongest possible checks are used as guarantees.
1271 if (context->lower_bound_guarantee() != NULL &&
1272 context->lower_bound_guarantee() != this) {
1273 if (context->lower_bound_guarantee()->IsBoundsCheck()) {
1274 HBoundsCheck* guarantee = HBoundsCheck::cast(
1275 context->lower_bound_guarantee());
1276 if (guarantee->base()->ActualValue() == base()->ActualValue()
1277 && guarantee->scale() == scale()
1278 && guarantee->offset() > offset()) {
1279 context->set_lower_bound_guarantee(this);
1280 }
1281 }
1282 }
1283 if (context->upper_bound_guarantee() != NULL &&
1284 context->upper_bound_guarantee() != this) {
1285 if (context->upper_bound_guarantee()->IsBoundsCheck()) {
1286 HBoundsCheck* guarantee = HBoundsCheck::cast(
1287 context->upper_bound_guarantee());
1288 if (guarantee->base()->ActualValue() == base()->ActualValue()
1289 && guarantee->scale() == scale()
1290 && guarantee->offset() < offset()) {
1291 context->set_upper_bound_guarantee(this);
1292 }
1293 }
1294 }
1295
1012 // TODO(mmassi) 1296 // TODO(mmassi)
1013 // Instead of checking for "same basic block" we should check for 1297 // Instead of checking for "same basic block" we should check for
1014 // "dominates and postdominates". 1298 // "dominates and postdominates".
1015 if (context->upper_bound() == length() && 1299 if (context->upper_bound() == length() &&
1016 context->lower_bound_guarantee() != NULL && 1300 context->lower_bound_guarantee() != NULL &&
1017 context->lower_bound_guarantee() != this && 1301 context->lower_bound_guarantee() != this &&
1018 context->lower_bound_guarantee()->block() != block() && 1302 context->lower_bound_guarantee()->block() == block() &&
1019 offset() < context->offset() && 1303 offset() < context->offset() &&
1020 index_can_increase() && 1304 index_can_increase() &&
1021 context->upper_bound_guarantee() == NULL) { 1305 context->upper_bound_guarantee() == NULL) {
1022 offset_ = context->offset(); 1306 offset_ = context->offset();
1023 SetResponsibilityForRange(DIRECTION_UPPER); 1307 SetResponsibilityForRange(DIRECTION_UPPER);
1024 context->set_upper_bound_guarantee(this); 1308 context->set_upper_bound_guarantee(this);
1309 block()->graph()->ClearRelationsTable();
1025 } else if (context->upper_bound_guarantee() != NULL && 1310 } else if (context->upper_bound_guarantee() != NULL &&
1026 context->upper_bound_guarantee() != this && 1311 context->upper_bound_guarantee() != this &&
1027 context->upper_bound_guarantee()->block() != block() && 1312 context->upper_bound_guarantee()->block() == block() &&
1028 offset() > context->offset() && 1313 offset() > context->offset() &&
1029 index_can_decrease() && 1314 index_can_decrease() &&
1030 context->lower_bound_guarantee() == NULL) { 1315 context->lower_bound_guarantee() == NULL) {
1031 offset_ = context->offset(); 1316 offset_ = context->offset();
1032 SetResponsibilityForRange(DIRECTION_LOWER); 1317 SetResponsibilityForRange(DIRECTION_LOWER);
1033 context->set_lower_bound_guarantee(this); 1318 context->set_lower_bound_guarantee(this);
1319 block()->graph()->ClearRelationsTable();
1034 } 1320 }
1035 } 1321 }
1036 1322
1037 1323
1038 void HBoundsCheck::ApplyIndexChange() { 1324 void HBoundsCheck::ApplyIndexChange() {
1039 if (skip_check()) return; 1325 if (skip_check() || base() == NULL) return;
1040 1326
1041 DecompositionResult decomposition; 1327 DecompositionResult decomposition;
1042 bool index_is_decomposable = index()->TryDecompose(&decomposition); 1328 bool index_is_decomposable = index()->TryDecompose(&decomposition);
1043 if (index_is_decomposable) { 1329 if (index_is_decomposable) {
1044 ASSERT(decomposition.base() == base()); 1330 ASSERT(decomposition.base() == base());
1045 if (decomposition.offset() == offset() && 1331 if (decomposition.offset() == offset() &&
1046 decomposition.scale() == scale()) return; 1332 decomposition.scale() == scale()) return;
1047 } else { 1333 } else {
1048 return; 1334 return;
1049 } 1335 }
1050 1336
1051 ReplaceAllUsesWith(index()); 1337 ReplaceAllUsesWith(index());
1052 1338
1053 HValue* current_index = decomposition.base(); 1339 HValue* current_index = decomposition.base();
1054 int actual_offset = decomposition.offset() + offset();
1055 int actual_scale = decomposition.scale() + scale();
1056 1340
1057 if (actual_offset != 0) { 1341 if (offset() != 0) {
1058 HConstant* add_offset = new(block()->graph()->zone()) HConstant( 1342 HConstant* add_offset = new(block()->graph()->zone()) HConstant(
1059 actual_offset, index()->representation()); 1343 offset(), index()->representation());
1060 add_offset->InsertBefore(this); 1344 add_offset->InsertBefore(this);
1061 HInstruction* add = HAdd::New(block()->graph()->zone(), 1345 HInstruction* add = HAdd::New(block()->graph()->zone(),
1062 block()->graph()->GetInvalidContext(), current_index, add_offset); 1346 block()->graph()->GetInvalidContext(), current_index, add_offset);
1063 add->InsertBefore(this); 1347 add->InsertBefore(this);
1064 add->AssumeRepresentation(index()->representation()); 1348 add->AssumeRepresentation(index()->representation());
1065 current_index = add; 1349 current_index = add;
1066 } 1350 }
1067 1351
1068 if (actual_scale != 0) { 1352 if (scale() != 0) {
1069 HConstant* sar_scale = new(block()->graph()->zone()) HConstant( 1353 HConstant* sar_scale = new(block()->graph()->zone()) HConstant(
1070 actual_scale, index()->representation()); 1354 scale(), index()->representation());
1071 sar_scale->InsertBefore(this); 1355 sar_scale->InsertBefore(this);
1072 HInstruction* sar = HSar::New(block()->graph()->zone(), 1356 HInstruction* sar = HSar::New(block()->graph()->zone(),
1073 block()->graph()->GetInvalidContext(), current_index, sar_scale); 1357 block()->graph()->GetInvalidContext(), current_index, sar_scale);
1074 sar->InsertBefore(this); 1358 sar->InsertBefore(this);
1075 sar->AssumeRepresentation(index()->representation()); 1359 sar->AssumeRepresentation(index()->representation());
1076 current_index = sar; 1360 current_index = sar;
1077 } 1361 }
1078 1362
1079 SetOperandAt(0, current_index); 1363 SetOperandAt(0, current_index);
1080 1364
1081 base_ = NULL; 1365 base_ = NULL;
1082 offset_ = 0; 1366 offset_ = 0;
1083 scale_ = 0; 1367 scale_ = 0;
1084 responsibility_direction_ = DIRECTION_NONE; 1368 responsibility_direction_ = DIRECTION_NONE;
1085 } 1369 }
1086 1370
1087 1371
1088 void HBoundsCheck::AddInformativeDefinitions() { 1372 void HBoundsCheck::AddInformativeDefinitions() {
1089 // TODO(mmassi): Executing this code during AddInformativeDefinitions 1373 if (DetectCompoundIndex()) {
1090 // is a hack. Move it to some other HPhase. 1374 HBoundsCheckBaseIndexInformation* base_index_info =
1091 if (FLAG_array_bounds_checks_elimination) { 1375 new(block()->graph()->zone())
1092 if (index()->TryGuaranteeRange(length())) { 1376 HBoundsCheckBaseIndexInformation(this);
1093 set_skip_check(true); 1377 base_index_info->InsertAfter(this);
1094 }
1095 if (DetectCompoundIndex()) {
1096 HBoundsCheckBaseIndexInformation* base_index_info =
1097 new(block()->graph()->zone())
1098 HBoundsCheckBaseIndexInformation(this);
1099 base_index_info->InsertAfter(this);
1100 }
1101 } 1378 }
1102 } 1379 }
1103 1380
1104 1381
1105 bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation, 1382 bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation,
1106 HValue* related_value, 1383 HValue* related_value,
1107 int offset, 1384 int offset,
1108 int scale) { 1385 int scale) {
1109 if (related_value == length()) { 1386 if (related_value == length()) {
1110 // A HBoundsCheck is smaller than the length it compared against. 1387 // A HBoundsCheck is smaller than the length it compared against.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 } 1435 }
1159 UpdateRepresentation(r, h_infer, "boundscheck"); 1436 UpdateRepresentation(r, h_infer, "boundscheck");
1160 } 1437 }
1161 1438
1162 1439
1163 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal( 1440 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal(
1164 NumericRelation relation, 1441 NumericRelation relation,
1165 HValue* related_value, 1442 HValue* related_value,
1166 int offset, 1443 int offset,
1167 int scale) { 1444 int scale) {
1445 if (bounds_check() == NULL) return false;
1446
1168 if (related_value == bounds_check()->length()) { 1447 if (related_value == bounds_check()->length()) {
1169 return NumericRelation::Lt().CompoundImplies( 1448 return NumericRelation::Lt().CompoundImplies(
1170 relation, 1449 relation,
1171 bounds_check()->offset(), bounds_check()->scale(), offset, scale); 1450 bounds_check()->offset(), bounds_check()->scale(), offset, scale);
1172 } else if (related_value == block()->graph()->GetConstant0()) { 1451 } else if (related_value == block()->graph()->GetConstant0()) {
1173 return NumericRelation::Ge().CompoundImplies( 1452 return NumericRelation::Ge().CompoundImplies(
1174 relation, 1453 relation,
1175 bounds_check()->offset(), bounds_check()->scale(), offset, scale); 1454 bounds_check()->offset(), bounds_check()->scale(), offset, scale);
1176 } else { 1455 } else {
1177 return false; 1456 return false;
1178 } 1457 }
1179 } 1458 }
1180 1459
1181 1460
1182 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) { 1461 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) {
1183 stream->Add("base: "); 1462 stream->Add("base: ");
1184 base_index()->PrintNameTo(stream); 1463 base_index()->PrintNameTo(stream);
1185 stream->Add(", check: "); 1464 stream->Add(", check: ");
1186 base_index()->PrintNameTo(stream); 1465 if (bounds_check() != NULL) {
1466 bounds_check()->PrintNameTo(stream);
1467 } else {
1468 stream->Add("DISCONNECTED ");
1469 OperandAt(1)->PrintNameTo(stream);
1470 }
1187 } 1471 }
1188 1472
1189 1473
1190 void HCallConstantFunction::PrintDataTo(StringStream* stream) { 1474 void HCallConstantFunction::PrintDataTo(StringStream* stream) {
1191 if (IsApplyFunction()) { 1475 if (IsApplyFunction()) {
1192 stream->Add("optimized apply "); 1476 stream->Add("optimized apply ");
1193 } else { 1477 } else {
1194 stream->Add("%o ", function()->shared()->DebugName()); 1478 stream->Add("%o ", function()->shared()->DebugName());
1195 } 1479 }
1196 stream->Add("#%d", argument_count()); 1480 stream->Add("#%d", argument_count());
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 ClearFlag(HValue::kCanBeDivByZero); 2108 ClearFlag(HValue::kCanBeDivByZero);
1825 } 2109 }
1826 return result; 2110 return result;
1827 } else { 2111 } else {
1828 return HValue::InferRange(zone); 2112 return HValue::InferRange(zone);
1829 } 2113 }
1830 } 2114 }
1831 2115
1832 2116
1833 void HPhi::AddInformativeDefinitions() { 2117 void HPhi::AddInformativeDefinitions() {
1834 if (OperandCount() == 2) { 2118 HLoopInformation* my_loop = block()->current_loop();
2119
2120 if (OperandCount() == 2 && my_loop != NULL) {
1835 // If one of the operands is an OSR block give up (this cannot be an 2121 // If one of the operands is an OSR block give up (this cannot be an
1836 // induction variable). 2122 // induction variable).
1837 if (OperandAt(0)->block()->is_osr_entry() || 2123 if (OperandAt(0)->block()->is_osr_entry() ||
1838 OperandAt(1)->block()->is_osr_entry()) return; 2124 OperandAt(1)->block()->is_osr_entry()) return;
1839 2125
1840 for (int operand_index = 0; operand_index < 2; operand_index++) { 2126 for (int operand_index = 0; operand_index < 2; operand_index++) {
1841 int other_operand_index = (operand_index + 1) % 2; 2127 int other_operand_index = (operand_index + 1) % 2;
1842 2128
2129 HValue* induction_base_candidate = OperandAt(other_operand_index);
2130 HLoopInformation* base_block_loop =
2131 induction_base_candidate->block()->current_loop();
2132 if (base_block_loop != NULL &&
2133 (base_block_loop == my_loop ||
2134 base_block_loop->IsNestedInThisLoop(my_loop))) continue;
2135
1843 static NumericRelation relations[] = { 2136 static NumericRelation relations[] = {
1844 NumericRelation::Ge(), 2137 NumericRelation::Gt(),
1845 NumericRelation::Le() 2138 NumericRelation::Lt()
1846 }; 2139 };
1847 2140
1848 // Check if this phi is an induction variable. If, e.g., we know that 2141 // Check if this phi is an induction variable. If, e.g., we know that
1849 // its first input is greater than the phi itself, then that must be 2142 // its first input is greater than the phi itself, then that must be
1850 // the back edge, and the phi is always greater than its second input. 2143 // the back edge, and the phi is always greater than its second input.
1851 for (int relation_index = 0; relation_index < 2; relation_index++) { 2144 for (int relation_index = 0; relation_index < 2; relation_index++) {
1852 if (OperandAt(operand_index)->IsRelationTrue(relations[relation_index], 2145 if (OperandAt(operand_index)->IsRelationTrue(relations[relation_index],
1853 this)) { 2146 this)) {
1854 HInductionVariableAnnotation::AddToGraph(this, 2147 HInductionVariableAnnotation::AddToGraph(this,
1855 relations[relation_index], 2148 relations[relation_index],
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
2405 stream->Add(Token::Name(token())); 2698 stream->Add(Token::Name(token()));
2406 stream->Add(" "); 2699 stream->Add(" ");
2407 HControlInstruction::PrintDataTo(stream); 2700 HControlInstruction::PrintDataTo(stream);
2408 } 2701 }
2409 2702
2410 2703
2411 void HCompareIDAndBranch::AddInformativeDefinitions() { 2704 void HCompareIDAndBranch::AddInformativeDefinitions() {
2412 NumericRelation r = NumericRelation::FromToken(token()); 2705 NumericRelation r = NumericRelation::FromToken(token());
2413 if (r.IsNone()) return; 2706 if (r.IsNone()) return;
2414 2707
2415 HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first());
2416 HNumericConstraint::AddToGraph( 2708 HNumericConstraint::AddToGraph(
2417 left(), r.Negated(), right(), SuccessorAt(1)->first()); 2709 left(), r, right(), SuccessorAt(0)->first(), SuccessorAt(1));
2710 HNumericConstraint::AddToGraph(
2711 left(), r.Negated(), right(), SuccessorAt(1)->first(), SuccessorAt(0));
2418 } 2712 }
2419 2713
2420 2714
2421 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { 2715 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) {
2422 stream->Add(Token::Name(token())); 2716 stream->Add(Token::Name(token()));
2423 stream->Add(" "); 2717 stream->Add(" ");
2424 left()->PrintNameTo(stream); 2718 left()->PrintNameTo(stream);
2425 stream->Add(" "); 2719 stream->Add(" ");
2426 right()->PrintNameTo(stream); 2720 right()->PrintNameTo(stream);
2427 HControlInstruction::PrintDataTo(stream); 2721 HControlInstruction::PrintDataTo(stream);
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
3144 visited->Add(id()); 3438 visited->Add(id());
3145 // Propagate to the left argument. If the left argument cannot be -0, then 3439 // Propagate to the left argument. If the left argument cannot be -0, then
3146 // the result of the sub operation cannot be either. 3440 // the result of the sub operation cannot be either.
3147 if (range() == NULL || range()->CanBeMinusZero()) { 3441 if (range() == NULL || range()->CanBeMinusZero()) {
3148 return left(); 3442 return left();
3149 } 3443 }
3150 return NULL; 3444 return NULL;
3151 } 3445 }
3152 3446
3153 3447
3448 bool HAdd::IsRelationTrueInternal(NumericRelation relation,
3449 HValue* other,
3450 int offset,
3451 int scale) {
3452 if (offset != 0 || scale != 0) return false;
3453
3454 // We look for a pattern like "x + delta rel x", where we should return
3455 // true if "delta >= 0 && rel.IsExtendable(1)" or
3456 // "delta <= 0 && rel.IsExtendable(-1)".
3457 HValue* delta = NULL;
3458 if (left()->ActualValue() == other->ActualValue()) {
3459 delta = right();
3460 } else if (right()->ActualValue() == other->ActualValue()) {
3461 delta = left();
3462 } else {
3463 return false;
3464 }
3465
3466 if (relation.IsExtendable(1) &&
3467 delta->IsRelationTrue(NumericRelation::Ge(),
3468 block()->graph()->GetConstant0())) {
3469 return true;
3470 }
3471
3472 if (relation.IsExtendable(-1) &&
3473 delta->IsRelationTrue(NumericRelation::Le(),
3474 block()->graph()->GetConstant0())) {
3475 return true;
3476 }
3477
3478 return false;
3479 }
3480
3481
3154 bool HStoreKeyed::NeedsCanonicalization() { 3482 bool HStoreKeyed::NeedsCanonicalization() {
3155 // If value is an integer or smi or comes from the result of a keyed load or 3483 // If value is an integer or smi or comes from the result of a keyed load or
3156 // constant then it is either be a non-hole value or in the case of a constant 3484 // constant then it is either be a non-hole value or in the case of a constant
3157 // the hole is only being stored explicitly: no need for canonicalization. 3485 // the hole is only being stored explicitly: no need for canonicalization.
3158 // 3486 //
3159 // The exception to that is keyed loads from external float or double arrays: 3487 // The exception to that is keyed loads from external float or double arrays:
3160 // these can load arbitrary representation of NaN. 3488 // these can load arbitrary representation of NaN.
3161 3489
3162 if (value()->IsConstant()) { 3490 if (value()->IsConstant()) {
3163 return false; 3491 return false;
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
3662 3990
3663 3991
3664 void HCheckFunction::Verify() { 3992 void HCheckFunction::Verify() {
3665 HInstruction::Verify(); 3993 HInstruction::Verify();
3666 ASSERT(HasNoUses()); 3994 ASSERT(HasNoUses());
3667 } 3995 }
3668 3996
3669 #endif 3997 #endif
3670 3998
3671 } } // namespace v8::internal 3999 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698