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

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: Created 7 years, 8 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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 } 166 }
167 } 167 }
168 168
169 169
170 // This method is recursive but it is guaranteed to terminate because 170 // This method is recursive but it is guaranteed to terminate because
171 // RedefinedOperand() always dominates "this". 171 // RedefinedOperand() always dominates "this".
172 bool HValue::IsRelationTrue(NumericRelation relation, 172 bool HValue::IsRelationTrue(NumericRelation relation,
173 HValue* other, 173 HValue* other,
174 int offset, 174 int offset,
175 int scale) { 175 int scale) {
176 if (this == other) { 176 if (ActualValue() == other->ActualValue()) {
177 return scale == 0 && relation.IsExtendable(offset); 177 return scale == 0 && relation.IsExtendable(offset);
178 } 178 }
179 179
180 // Test the direct relation. 180 // Test the direct relation.
181 if (IsRelationTrueInternal(relation, other, offset, scale)) return true; 181 if (IsRelationTrueInternal(relation, other, offset, scale)) return true;
182 182
183 // If scale is 0 try the reversed relation. 183 // If scale is 0 try the reversed relation.
184 if (scale == 0 && 184 if (scale == 0 &&
185 // TODO(mmassi): do we need the full, recursive IsRelationTrue? 185 // TODO(mmassi): do we need the full, recursive IsRelationTrue?
186 other->IsRelationTrueInternal(relation.Reversed(), this, -offset)) { 186 other->IsRelationTrueInternal(relation.Reversed(), this, -offset)) {
187 return true; 187 return true;
188 } 188 }
189 189
190 // Try decomposition (but do not accept scaled compounds). 190 // Try decomposition, but only if we are not scaled.
191 DecompositionResult decomposition; 191 DecompositionResult decomposition;
192 if (TryDecompose(&decomposition) && 192 if (scale == 0 && TryDecompose(&decomposition)) {
193 decomposition.scale() == 0 && 193 // Check if the compound is scaled.
194 decomposition.base()->IsRelationTrue(relation, other, 194 if (decomposition.scale() == 0) {
195 offset + decomposition.offset(), 195 // Non-scaled compounds can be handled normally.
196 scale)) { 196 if (decomposition.base()->IsRelationTrue(
197 return true; 197 relation, other, offset + decomposition.offset(), scale)) {
198 return true;
199 }
200 } else if (decomposition.offset() == 0 && offset == 0) {
201 // We only have a scale value which means that we can apply chaining
202 // using relation extensibility: negative scales grow values (positive
203 // direction), positive scales make them smaller (negative direction).
204 // As a concrete example: "(x << 1) <= 0" <== "x <= 0".
205 int direction = decomposition.scale() > 0 ? -1 : 1;
Jakob Kummerow 2013/04/17 11:34:15 why not just "int direction = -decomposition.scale
Massi 2013/05/07 11:32:03 Done.
206 if (relation.IsExtendable(direction)
207 && decomposition.base()->IsRelationTrue(
Jakob Kummerow 2013/04/17 11:34:15 nit: '&&' on the previous line please
Massi 2013/05/07 11:32:03 Done.
208 relation, other, 0, 0)) {
Jakob Kummerow 2013/04/17 11:34:15 nit: fits on last line?
Massi 2013/05/07 11:32:03 Done.
209 return true;
210 }
211
212 } else {
213 // Just test for "same value" relation extensibility.
214
215 if (decomposition.base() == other) {
216 // The direction of the extensibility test is determined by scale and
217 // offset, but we can not handle all combinations.
218 int direction = 0;
219 // Do not accept left shifts greater than 1.
220 if (decomposition.scale() <= -1) {
221 if (decomposition.offset() == 0) {
222 // A positive scale makes values smaller.
223 direction = -decomposition.scale();
224 } else {
225 // If offset and scale have different signs they both go in the
226 // same direction, otherwise we cannot handle the combination.
227 if (decomposition.offset() * decomposition.scale() < 0) {
228 direction = offset;
229 }
230 }
231 }
232
233 if (direction != 0 && relation.IsExtendable(direction)) {
234 return true;
235 }
236 }
237 }
198 } 238 }
199 239
200 // Pass the request to the redefined value. 240 // Pass the request to the redefined value.
201 HValue* redefined = RedefinedOperand(); 241 HValue* redefined = RedefinedOperand();
202 return redefined != NULL && redefined->IsRelationTrue(relation, other, 242 return redefined != NULL && redefined->IsRelationTrue(relation, other,
203 offset, scale); 243 offset, scale);
204 } 244 }
205 245
206 246
207 bool HValue::TryGuaranteeRange(HValue* upper_bound) { 247 bool HValue::TryGuaranteeRange(HValue* upper_bound,
208 RangeEvaluationContext context = RangeEvaluationContext(this, upper_bound); 248 HBasicBlock* starting_block_for_hoisting) {
249 if (starting_block_for_hoisting == NULL) {
250 starting_block_for_hoisting = block();
251 }
252 RangeEvaluationContext context = RangeEvaluationContext(
253 this, upper_bound, starting_block_for_hoisting);
209 TryGuaranteeRangeRecursive(&context); 254 TryGuaranteeRangeRecursive(&context);
210 bool result = context.is_range_satisfied(); 255 bool result = context.is_range_satisfied();
211 if (result) { 256 if (result) {
212 context.lower_bound_guarantee()->SetResponsibilityForRange(DIRECTION_LOWER); 257 context.lower_bound_guarantee()->SetResponsibilityForRange(DIRECTION_LOWER);
213 context.upper_bound_guarantee()->SetResponsibilityForRange(DIRECTION_UPPER); 258 context.upper_bound_guarantee()->SetResponsibilityForRange(DIRECTION_UPPER);
214 } 259 }
215 return result; 260 return result;
216 } 261 }
217 262
218 263
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 context->swap_candidate(&decomposition); 297 context->swap_candidate(&decomposition);
253 } 298 }
254 if (context->is_range_satisfied()) return; 299 if (context->is_range_satisfied()) return;
255 300
256 // Try to modify this to satisfy the constraint. 301 // Try to modify this to satisfy the constraint.
257 302
258 TryGuaranteeRangeChanging(context); 303 TryGuaranteeRangeChanging(context);
259 } 304 }
260 305
261 306
262 RangeEvaluationContext::RangeEvaluationContext(HValue* value, HValue* upper) 307 RangeEvaluationContext::RangeEvaluationContext(HValue* value,
263 : lower_bound_(upper->block()->graph()->GetConstant0()), 308 HValue* upper,
309 HBasicBlock* starting_block)
310 : starting_block_(starting_block),
311 lower_bound_(upper->block()->graph()->GetConstant0()),
264 lower_bound_guarantee_(NULL), 312 lower_bound_guarantee_(NULL),
265 candidate_(value), 313 candidate_(value),
266 upper_bound_(upper), 314 upper_bound_(upper),
267 upper_bound_guarantee_(NULL), 315 upper_bound_guarantee_(NULL),
268 offset_(0), 316 offset_(0),
269 scale_(0) { 317 scale_(0) {
270 } 318 }
271 319
272 320
273 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { 321 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) {
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 } 973 }
926 } 974 }
927 } 975 }
928 #endif 976 #endif
929 977
930 978
931 HNumericConstraint* HNumericConstraint::AddToGraph( 979 HNumericConstraint* HNumericConstraint::AddToGraph(
932 HValue* constrained_value, 980 HValue* constrained_value,
933 NumericRelation relation, 981 NumericRelation relation,
934 HValue* related_value, 982 HValue* related_value,
935 HInstruction* insertion_point) { 983 HInstruction* insertion_point,
984 HBasicBlock* other_block) {
936 if (insertion_point == NULL) { 985 if (insertion_point == NULL) {
937 if (constrained_value->IsInstruction()) { 986 if (constrained_value->IsInstruction()) {
938 insertion_point = HInstruction::cast(constrained_value); 987 insertion_point = HInstruction::cast(constrained_value);
939 } else if (constrained_value->IsPhi()) { 988 } else if (constrained_value->IsPhi()) {
940 insertion_point = constrained_value->block()->first(); 989 insertion_point = constrained_value->block()->first();
941 } else { 990 } else {
942 UNREACHABLE(); 991 UNREACHABLE();
943 } 992 }
944 } 993 }
945 HNumericConstraint* result = 994 HNumericConstraint* result =
946 new(insertion_point->block()->zone()) HNumericConstraint( 995 new(insertion_point->block()->zone()) HNumericConstraint(
947 constrained_value, relation, related_value); 996 constrained_value, relation, related_value, other_block);
948 result->InsertAfter(insertion_point); 997 result->InsertAfter(insertion_point);
949 return result; 998 return result;
950 } 999 }
951 1000
952 1001
953 void HNumericConstraint::PrintDataTo(StringStream* stream) { 1002 void HNumericConstraint::PrintDataTo(StringStream* stream) {
954 stream->Add("("); 1003 stream->Add("(");
955 constrained_value()->PrintNameTo(stream); 1004 constrained_value()->PrintNameTo(stream);
956 stream->Add(" %s ", relation().Mnemonic()); 1005 stream->Add(" %s ", relation().Mnemonic());
957 related_value()->PrintNameTo(stream); 1006 related_value()->PrintNameTo(stream);
958 stream->Add(")"); 1007 stream->Add(")");
959 } 1008 }
960 1009
961 1010
962 HInductionVariableAnnotation* HInductionVariableAnnotation::AddToGraph( 1011 HInductionVariableAnnotation* HInductionVariableAnnotation::AddToGraph(
963 HPhi* phi, 1012 HPhi* phi,
964 NumericRelation relation, 1013 NumericRelation relation,
965 int operand_index) { 1014 int operand_index) {
966 HInductionVariableAnnotation* result = 1015 HInductionVariableAnnotation* result = new(phi->block()->zone())
967 new(phi->block()->zone()) HInductionVariableAnnotation(phi, relation, 1016 HInductionVariableAnnotation(phi, relation, operand_index,
968 operand_index); 1017 phi->block()->zone());
969 result->InsertAfter(phi->block()->first()); 1018 result->InsertAfter(phi->block()->first());
970 return result; 1019 return result;
971 } 1020 }
972 1021
973 1022
1023 void HInductionVariableAnnotation::AddHoistedCheck(HBoundsCheck* check) {
1024 hoisted_checks_.Add(check, block()->zone());
1025 }
1026
1027
1028 HInductionVariableAnnotation::HInductionVariableAnnotation(
1029 HPhi* phi,
1030 NumericRelation relation,
1031 int operand_index,
1032 Zone* zone)
1033 : HUnaryOperation(phi), phi_(phi), relation_(relation),
Jakob Kummerow 2013/04/17 11:34:15 nit: one line per initializer, please
Massi 2013/05/07 11:32:03 Done.
1034 operand_index_(operand_index), hoisted_checks_(4, zone) {
1035 }
1036
1037
1038 void HInductionVariableAnnotation::TryGuaranteeRangeChanging(
1039 RangeEvaluationContext* context) {
1040 if (relation().IsExtendable(1)) {
1041 if (context->lower_bound_guarantee() == NULL) return;
1042 } else {
1043 return;
1044 }
1045
1046 for (int i = 0; i < hoisted_checks()->length(); i++) {
1047 HBoundsCheck* hoisted_check = hoisted_checks()->at(i);
1048 if (hoisted_check->length()->ActualValue()
1049 == context->upper_bound()->ActualValue()) {
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
1050 context->set_upper_bound_guarantee(hoisted_check);
1051 return;
1052 }
1053 }
1054
1055 HBasicBlock* starting_block = context->starting_block();
1056 HLoopInformation* starting_loop = starting_block->current_loop();
1057 if (starting_loop == NULL) return;
1058 HLoopInformation* my_loop = block()->current_loop();
1059 if (my_loop == NULL) return;
1060 if (my_loop->exits_count() > 1
1061 && !block()->graph()->use_optimistic_licm()) return;
Jakob Kummerow 2013/04/17 11:34:15 If it doesn't make a significant difference, I'd r
1062
1063 bool starting_loop_is_nested_in_my_loop = false;
Jakob Kummerow 2013/04/17 11:34:15 we can make this loop a little simpler: // See
1064 while (starting_loop != NULL) {
1065 if (starting_loop == my_loop) {
1066 starting_loop_is_nested_in_my_loop = true;
1067 break;
1068 }
1069 starting_loop = starting_loop->parent_loop();
1070 }
1071 if (!starting_loop_is_nested_in_my_loop) return;
1072 starting_loop = starting_block->current_loop();
1073
1074 for (HValue* candidate = context->candidate();
1075 candidate != NULL;
1076 candidate = candidate->RedefinedOperand()) {
1077 if (candidate->IsNumericConstraint()) {
Jakob Kummerow 2013/04/17 11:34:15 for consistency with code below, I'd transform thi
Massi 2013/05/07 11:32:03 Done.
1078 HNumericConstraint* constraint = HNumericConstraint::cast(candidate);
1079 if (!constraint->relation().IsExtendable(-1)) continue;
1080 HLoopInformation* other_loop = constraint->other_block()->current_loop();
1081 if (other_loop == my_loop) continue;
1082
1083 HBasicBlock* my_header = my_loop->loop_header();
1084 HBasicBlock* my_pre_header = my_header->predecessors()->at(0);
1085
1086 HValue* induction_limit = constraint->related_value()->ActualValue();
1087 HValue* upper_bound = context->upper_bound()->ActualValue();
1088
1089 if (induction_limit->block() != my_pre_header
1090 && !induction_limit->block()->Dominates(my_pre_header)) continue;
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
1091 if (upper_bound->block() != my_pre_header
1092 && !upper_bound->block()->Dominates(my_pre_header)) continue;
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
1093
1094 if (!(induction_limit->representation().Equals(
1095 upper_bound->representation())
1096 || induction_limit->IsInteger32Constant())) {
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
1097 continue;
1098 }
1099
1100 HBoundsCheck* check = new(block()->zone()) HBoundsCheck(
1101 induction_limit, upper_bound);
1102 check->InsertBefore(my_pre_header->end());
1103 check->set_allow_equality(true);
1104 check->UpdateRedefinedUses();
1105 AddHoistedCheck(check);
1106 context->set_upper_bound_guarantee(check);
1107 return;
1108 }
1109 }
1110 }
1111
1112
974 void HInductionVariableAnnotation::PrintDataTo(StringStream* stream) { 1113 void HInductionVariableAnnotation::PrintDataTo(StringStream* stream) {
975 stream->Add("("); 1114 stream->Add("(");
976 RedefinedOperand()->PrintNameTo(stream); 1115 RedefinedOperand()->PrintNameTo(stream);
977 stream->Add(" %s ", relation().Mnemonic()); 1116 stream->Add(" %s ", relation().Mnemonic());
978 induction_base()->PrintNameTo(stream); 1117 induction_base()->PrintNameTo(stream);
979 stream->Add(")"); 1118 stream->Add(")");
980 } 1119 }
981 1120
982 1121
983 void HDummyUse::PrintDataTo(StringStream* stream) { 1122 void HDummyUse::PrintDataTo(StringStream* stream) {
(...skipping 16 matching lines...) Expand all
1000 stream->Add("#%d", argument_count()); 1139 stream->Add("#%d", argument_count());
1001 } 1140 }
1002 1141
1003 1142
1004 void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) { 1143 void HBoundsCheck::TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
1005 if (context->candidate()->ActualValue() != base()->ActualValue() || 1144 if (context->candidate()->ActualValue() != base()->ActualValue() ||
1006 context->scale() < scale()) { 1145 context->scale() < scale()) {
1007 return; 1146 return;
1008 } 1147 }
1009 1148
1149 if (context->lower_bound_guarantee() != NULL &&
1150 context->lower_bound_guarantee() != this) {
1151 if (context->lower_bound_guarantee()->IsBoundsCheck()) {
1152 HBoundsCheck* guarantee = HBoundsCheck::cast(
1153 context->lower_bound_guarantee());
1154 if (guarantee->base()->ActualValue() == base()->ActualValue()
1155 && guarantee->scale() == scale()
1156 && guarantee->offset() > offset()) {
1157 context->set_lower_bound_guarantee(this);
1158 }
1159 }
1160 } else if (context->upper_bound_guarantee() != NULL &&
Jakob Kummerow 2013/04/17 11:34:15 I think the "else" needs to be removed.
Massi 2013/05/07 11:32:03 Done.
Massi 2013/05/07 11:32:03 Done.
1161 context->upper_bound_guarantee() != this) {
1162 if (context->upper_bound_guarantee()->IsBoundsCheck()) {
1163 HBoundsCheck* guarantee = HBoundsCheck::cast(
1164 context->upper_bound_guarantee());
1165 if (guarantee->base()->ActualValue() == base()->ActualValue()
1166 && guarantee->scale() == scale()
1167 && guarantee->offset() < offset()) {
1168 context->set_upper_bound_guarantee(this);
1169 }
1170 }
1171 }
1172
1010 // TODO(mmassi) 1173 // TODO(mmassi)
1011 // Instead of checking for "same basic block" we should check for 1174 // Instead of checking for "same basic block" we should check for
1012 // "dominates and postdominates". 1175 // "dominates and postdominates".
1013 if (context->upper_bound() == length() && 1176 if (context->upper_bound() == length() &&
1014 context->lower_bound_guarantee() != NULL && 1177 context->lower_bound_guarantee() != NULL &&
1015 context->lower_bound_guarantee() != this && 1178 context->lower_bound_guarantee() != this &&
1016 context->lower_bound_guarantee()->block() != block() && 1179 context->lower_bound_guarantee()->block() == block() &&
1017 offset() < context->offset() && 1180 offset() < context->offset() &&
1018 index_can_increase() && 1181 index_can_increase() &&
1019 context->upper_bound_guarantee() == NULL) { 1182 context->upper_bound_guarantee() == NULL) {
1020 offset_ = context->offset(); 1183 offset_ = context->offset();
1021 SetResponsibilityForRange(DIRECTION_UPPER); 1184 SetResponsibilityForRange(DIRECTION_UPPER);
1022 context->set_upper_bound_guarantee(this); 1185 context->set_upper_bound_guarantee(this);
1023 } else if (context->upper_bound_guarantee() != NULL && 1186 } else if (context->upper_bound_guarantee() != NULL &&
1024 context->upper_bound_guarantee() != this && 1187 context->upper_bound_guarantee() != this &&
1025 context->upper_bound_guarantee()->block() != block() && 1188 context->upper_bound_guarantee()->block() == block() &&
1026 offset() > context->offset() && 1189 offset() > context->offset() &&
1027 index_can_decrease() && 1190 index_can_decrease() &&
1028 context->lower_bound_guarantee() == NULL) { 1191 context->lower_bound_guarantee() == NULL) {
1029 offset_ = context->offset(); 1192 offset_ = context->offset();
1030 SetResponsibilityForRange(DIRECTION_LOWER); 1193 SetResponsibilityForRange(DIRECTION_LOWER);
1031 context->set_lower_bound_guarantee(this); 1194 context->set_lower_bound_guarantee(this);
1032 } 1195 }
1033 } 1196 }
1034 1197
1035 1198
1036 void HBoundsCheck::ApplyIndexChange() { 1199 void HBoundsCheck::ApplyIndexChange() {
1037 if (skip_check()) return; 1200 if (skip_check() || base() == NULL) return;
1038 1201
1039 DecompositionResult decomposition; 1202 DecompositionResult decomposition;
1040 bool index_is_decomposable = index()->TryDecompose(&decomposition); 1203 bool index_is_decomposable = index()->TryDecompose(&decomposition);
1041 if (index_is_decomposable) { 1204 if (index_is_decomposable) {
1042 ASSERT(decomposition.base() == base()); 1205 ASSERT(decomposition.base() == base());
1043 if (decomposition.offset() == offset() && 1206 if (decomposition.offset() == offset() &&
1044 decomposition.scale() == scale()) return; 1207 decomposition.scale() == scale()) return;
1045 } else { 1208 } else {
1046 return; 1209 return;
1047 } 1210 }
1048 1211
1049 ReplaceAllUsesWith(index()); 1212 ReplaceAllUsesWith(index());
1050 1213
1051 HValue* current_index = decomposition.base(); 1214 HValue* current_index = decomposition.base();
1052 int actual_offset = decomposition.offset() + offset();
1053 int actual_scale = decomposition.scale() + scale();
1054 1215
1055 if (actual_offset != 0) { 1216 if (offset() != 0) {
1056 HConstant* add_offset = new(block()->graph()->zone()) HConstant( 1217 HConstant* add_offset = new(block()->graph()->zone()) HConstant(
1057 actual_offset, index()->representation()); 1218 offset(), index()->representation());
1058 add_offset->InsertBefore(this); 1219 add_offset->InsertBefore(this);
1059 HInstruction* add = HAdd::New(block()->graph()->zone(), 1220 HInstruction* add = HAdd::New(block()->graph()->zone(),
1060 block()->graph()->GetInvalidContext(), current_index, add_offset); 1221 block()->graph()->GetInvalidContext(), current_index, add_offset);
1061 add->InsertBefore(this); 1222 add->InsertBefore(this);
1062 add->AssumeRepresentation(index()->representation()); 1223 add->AssumeRepresentation(index()->representation());
1063 current_index = add; 1224 current_index = add;
1064 } 1225 }
1065 1226
1066 if (actual_scale != 0) { 1227 if (scale() != 0) {
1067 HConstant* sar_scale = new(block()->graph()->zone()) HConstant( 1228 HConstant* sar_scale = new(block()->graph()->zone()) HConstant(
1068 actual_scale, index()->representation()); 1229 scale(), index()->representation());
1069 sar_scale->InsertBefore(this); 1230 sar_scale->InsertBefore(this);
1070 HInstruction* sar = HSar::New(block()->graph()->zone(), 1231 HInstruction* sar = HSar::New(block()->graph()->zone(),
1071 block()->graph()->GetInvalidContext(), current_index, sar_scale); 1232 block()->graph()->GetInvalidContext(), current_index, sar_scale);
1072 sar->InsertBefore(this); 1233 sar->InsertBefore(this);
1073 sar->AssumeRepresentation(index()->representation()); 1234 sar->AssumeRepresentation(index()->representation());
1074 current_index = sar; 1235 current_index = sar;
1075 } 1236 }
1076 1237
1077 SetOperandAt(0, current_index); 1238 SetOperandAt(0, current_index);
1078 1239
1079 base_ = NULL; 1240 base_ = NULL;
1080 offset_ = 0; 1241 offset_ = 0;
1081 scale_ = 0; 1242 scale_ = 0;
1082 responsibility_direction_ = DIRECTION_NONE; 1243 responsibility_direction_ = DIRECTION_NONE;
1083 } 1244 }
1084 1245
1085 1246
1086 void HBoundsCheck::AddInformativeDefinitions() { 1247 void HBoundsCheck::AddInformativeDefinitions() {
1087 // TODO(mmassi): Executing this code during AddInformativeDefinitions 1248 // TODO(mmassi): Executing this code during AddInformativeDefinitions
1088 // is a hack. Move it to some other HPhase. 1249 // is a hack. Move it to some other HPhase.
1089 if (FLAG_array_bounds_checks_elimination) { 1250 if (FLAG_array_bounds_checks_elimination) {
1090 if (index()->TryGuaranteeRange(length())) { 1251 if (index()->TryGuaranteeRange(length(), block())) {
1091 set_skip_check(true); 1252 set_skip_check(true);
1092 } 1253 }
1093 if (DetectCompoundIndex()) { 1254 if (DetectCompoundIndex()) {
1094 HBoundsCheckBaseIndexInformation* base_index_info = 1255 HBoundsCheckBaseIndexInformation* base_index_info =
1095 new(block()->graph()->zone()) 1256 new(block()->graph()->zone())
1096 HBoundsCheckBaseIndexInformation(this); 1257 HBoundsCheckBaseIndexInformation(this);
1097 base_index_info->InsertAfter(this); 1258 base_index_info->InsertAfter(this);
1098 } 1259 }
1099 } 1260 }
1100 } 1261 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 } 1317 }
1157 UpdateRepresentation(r, h_infer, "boundscheck"); 1318 UpdateRepresentation(r, h_infer, "boundscheck");
1158 } 1319 }
1159 1320
1160 1321
1161 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal( 1322 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal(
1162 NumericRelation relation, 1323 NumericRelation relation,
1163 HValue* related_value, 1324 HValue* related_value,
1164 int offset, 1325 int offset,
1165 int scale) { 1326 int scale) {
1327 if (bounds_check() == NULL) return false;
1328
1166 if (related_value == bounds_check()->length()) { 1329 if (related_value == bounds_check()->length()) {
1167 return NumericRelation::Lt().CompoundImplies( 1330 return NumericRelation::Lt().CompoundImplies(
1168 relation, 1331 relation,
1169 bounds_check()->offset(), bounds_check()->scale(), offset, scale); 1332 bounds_check()->offset(), bounds_check()->scale(), offset, scale);
1170 } else if (related_value == block()->graph()->GetConstant0()) { 1333 } else if (related_value == block()->graph()->GetConstant0()) {
1171 return NumericRelation::Ge().CompoundImplies( 1334 return NumericRelation::Ge().CompoundImplies(
1172 relation, 1335 relation,
1173 bounds_check()->offset(), bounds_check()->scale(), offset, scale); 1336 bounds_check()->offset(), bounds_check()->scale(), offset, scale);
1174 } else { 1337 } else {
1175 return false; 1338 return false;
1176 } 1339 }
1177 } 1340 }
1178 1341
1179 1342
1180 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) { 1343 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) {
1181 stream->Add("base: "); 1344 stream->Add("base: ");
1182 base_index()->PrintNameTo(stream); 1345 base_index()->PrintNameTo(stream);
1183 stream->Add(", check: "); 1346 stream->Add(", check: ");
1184 base_index()->PrintNameTo(stream); 1347 if (bounds_check() != NULL) {
1348 bounds_check()->PrintNameTo(stream);
1349 } else {
1350 stream->Add("DISCONNECTED ");
1351 OperandAt(1)->PrintNameTo(stream);
1352 }
1185 } 1353 }
1186 1354
1187 1355
1188 void HCallConstantFunction::PrintDataTo(StringStream* stream) { 1356 void HCallConstantFunction::PrintDataTo(StringStream* stream) {
1189 if (IsApplyFunction()) { 1357 if (IsApplyFunction()) {
1190 stream->Add("optimized apply "); 1358 stream->Add("optimized apply ");
1191 } else { 1359 } else {
1192 stream->Add("%o ", function()->shared()->DebugName()); 1360 stream->Add("%o ", function()->shared()->DebugName());
1193 } 1361 }
1194 stream->Add("#%d", argument_count()); 1362 stream->Add("#%d", argument_count());
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after
2337 stream->Add(Token::Name(token())); 2505 stream->Add(Token::Name(token()));
2338 stream->Add(" "); 2506 stream->Add(" ");
2339 HControlInstruction::PrintDataTo(stream); 2507 HControlInstruction::PrintDataTo(stream);
2340 } 2508 }
2341 2509
2342 2510
2343 void HCompareIDAndBranch::AddInformativeDefinitions() { 2511 void HCompareIDAndBranch::AddInformativeDefinitions() {
2344 NumericRelation r = NumericRelation::FromToken(token()); 2512 NumericRelation r = NumericRelation::FromToken(token());
2345 if (r.IsNone()) return; 2513 if (r.IsNone()) return;
2346 2514
2347 HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first());
2348 HNumericConstraint::AddToGraph( 2515 HNumericConstraint::AddToGraph(
2349 left(), r.Negated(), right(), SuccessorAt(1)->first()); 2516 left(), r, right(), SuccessorAt(0)->first(), SuccessorAt(1));
2517 HNumericConstraint::AddToGraph(
2518 left(), r.Negated(), right(), SuccessorAt(1)->first(), SuccessorAt(0));
2350 } 2519 }
2351 2520
2352 2521
2353 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { 2522 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) {
2354 stream->Add(Token::Name(token())); 2523 stream->Add(Token::Name(token()));
2355 stream->Add(" "); 2524 stream->Add(" ");
2356 left()->PrintNameTo(stream); 2525 left()->PrintNameTo(stream);
2357 stream->Add(" "); 2526 stream->Add(" ");
2358 right()->PrintNameTo(stream); 2527 right()->PrintNameTo(stream);
2359 HControlInstruction::PrintDataTo(stream); 2528 HControlInstruction::PrintDataTo(stream);
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
3031 visited->Add(id()); 3200 visited->Add(id());
3032 // Propagate to the left argument. If the left argument cannot be -0, then 3201 // Propagate to the left argument. If the left argument cannot be -0, then
3033 // the result of the sub operation cannot be either. 3202 // the result of the sub operation cannot be either.
3034 if (range() == NULL || range()->CanBeMinusZero()) { 3203 if (range() == NULL || range()->CanBeMinusZero()) {
3035 return left(); 3204 return left();
3036 } 3205 }
3037 return NULL; 3206 return NULL;
3038 } 3207 }
3039 3208
3040 3209
3210 bool HAdd::IsRelationTrueInternal(NumericRelation relation,
3211 HValue* other,
3212 int offset,
3213 int scale) {
3214 if (offset != 0 || scale != 0) return false;
3215
3216 // We look for a pattern like "x + delta rel x", where we should return
3217 // true if "delta >= 0 && rel.IsExtendable(1)" or
3218 // "delta <= 0 && rel.IsExtendable(-1)".
3219 HValue* delta = NULL;
3220 if (left()->ActualValue() == other->ActualValue()) {
3221 delta = right();
3222 } else if (right()->ActualValue() == other->ActualValue()) {
3223 delta = left();
3224 } else {
3225 return false;
3226 }
3227
3228 if (relation.IsExtendable(1)
3229 && delta->IsRelationTrue(NumericRelation::Ge(),
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
3230 block()->graph()->GetConstant0())) {
3231 return true;
3232 }
3233
3234 if (relation.IsExtendable(-1)
3235 && delta->IsRelationTrue(NumericRelation::Le(),
Jakob Kummerow 2013/04/17 11:34:15 nit: operator on the previous line
Massi 2013/05/07 11:32:03 Done.
3236 block()->graph()->GetConstant0())) {
3237 return true;
3238 }
3239
3240 return false;
3241 }
3242
3243
3041 bool HStoreKeyed::NeedsCanonicalization() { 3244 bool HStoreKeyed::NeedsCanonicalization() {
3042 // If value is an integer or smi or comes from the result of a keyed load or 3245 // 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 3246 // 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. 3247 // the hole is only being stored explicitly: no need for canonicalization.
3045 // 3248 //
3046 // The exception to that is keyed loads from external float or double arrays: 3249 // The exception to that is keyed loads from external float or double arrays:
3047 // these can load arbitrary representation of NaN. 3250 // these can load arbitrary representation of NaN.
3048 3251
3049 if (value()->IsConstant()) { 3252 if (value()->IsConstant()) {
3050 return false; 3253 return false;
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
3533 3736
3534 3737
3535 void HCheckFunction::Verify() { 3738 void HCheckFunction::Verify() {
3536 HInstruction::Verify(); 3739 HInstruction::Verify();
3537 ASSERT(HasNoUses()); 3740 ASSERT(HasNoUses());
3538 } 3741 }
3539 3742
3540 #endif 3743 #endif
3541 3744
3542 } } // namespace v8::internal 3745 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698