OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 void HValue::AddDependantsToWorklist(HInferRepresentation* h_infer) { | 153 void HValue::AddDependantsToWorklist(HInferRepresentation* h_infer) { |
154 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 154 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
155 h_infer->AddToWorklist(it.value()); | 155 h_infer->AddToWorklist(it.value()); |
156 } | 156 } |
157 for (int i = 0; i < OperandCount(); ++i) { | 157 for (int i = 0; i < OperandCount(); ++i) { |
158 h_infer->AddToWorklist(OperandAt(i)); | 158 h_infer->AddToWorklist(OperandAt(i)); |
159 } | 159 } |
160 } | 160 } |
161 | 161 |
162 | 162 |
163 bool HValue::TryGuaranteeRange(HValue* upper_bound) { | |
164 RangeEvaluationContext context = RangeEvaluationContext(this, upper_bound); | |
165 TryGuaranteeRangeRecursive(&context); | |
166 return context.RangeSatisfied(); | |
167 } | |
168 | |
169 | |
170 void HValue::TryGuaranteeRangeRecursive(RangeEvaluationContext* context) { | |
171 | |
172 if (FLAG_log_abcd) { | |
173 PrintF(" +++ TryGuaranteeRangeRecursive("); | |
174 SimplyPrint(); | |
175 PrintF(") {[LOWER "); | |
176 if (context->lower_check_satisfied()) { | |
177 context->lower_check_guarantee()->SimplyPrint(); | |
178 } else { | |
179 PrintF("NULL"); | |
180 } | |
181 PrintF("] "); | |
182 context->lower_bound()->SimplyPrint(); | |
183 PrintF(" <= ((x + %d) >> %d) ", context->offset(), context->scale()); | |
184 context->upper_bound()->SimplyPrint(); | |
185 PrintF(" [UPPER "); | |
186 if (context->upper_check_satisfied()) { | |
187 context->upper_check_guarantee()->SimplyPrint(); | |
188 } else { | |
189 PrintF("NULL"); | |
190 } | |
191 PrintF("]}\n"); | |
192 } | |
193 | |
194 | |
195 // Try to satisfy the lower bound on this value | |
Jakob Kummerow
2013/03/11 11:55:02
better comment:
// Check if we already know that t
| |
196 if (!context->lower_check_satisfied()) { | |
197 if (IsRelationTrueInternal(NumericRelation::Ge(), context->lower_bound(), | |
198 context->offset(), context->scale())) { | |
199 | |
200 if (FLAG_log_abcd) | |
201 PrintF(" ___ TryGuaranteeRangeRecursive(LOWER TRUE)\n"); | |
202 | |
203 context->set_lower_check_guarantee(this); | |
204 } | |
205 } | |
206 | |
207 // Try to satisfy the upper bound on this value | |
Jakob Kummerow
2013/03/11 11:55:02
better comment:
// Check if we already know that t
| |
208 if (!context->upper_check_satisfied()) { | |
209 if (IsRelationTrueInternal(NumericRelation::Lt(), context->upper_bound(), | |
210 context->offset(), context->scale()) || | |
211 (context->scale() == 0 && | |
212 context->upper_bound()->IsRelationTrue(NumericRelation::Gt(), | |
213 this, -context->offset()))) { | |
214 | |
215 if (FLAG_log_abcd) | |
216 PrintF(" ___ TryGuaranteeRangeRecursive(UPPER TRUE)\n"); | |
217 | |
218 context->set_upper_check_guarantee(this); | |
219 } | |
220 } | |
221 | |
222 if (context->RangeSatisfied()) return; | |
223 | |
224 // See if our RedefinedOperand() satisfies the constraints. | |
225 if (RedefinedOperand() != NULL) { | |
226 RedefinedOperand()->TryGuaranteeRangeRecursive(context); | |
227 } | |
228 if (context->RangeSatisfied()) return; | |
229 | |
230 // See if the constraints can be satisfied by decomposition. | |
Jakob Kummerow
2013/03/11 11:55:02
Why does this need to happen in the recursive call
Massi
2013/03/13 15:58:14
Because every definition of this value could be de
Jakob Kummerow
2013/03/14 12:50:08
OK, I see.
| |
231 HValue* base = NULL; | |
232 int offset = context->offset(); | |
233 int scale = context->scale(); | |
234 if (context->origin()->TryDecompose(&base, &offset, &scale)) { | |
235 context->swap_origin(base, offset, scale); | |
236 | |
237 if (FLAG_log_abcd) | |
238 PrintF(" ___ TryGuaranteeRangeRecursive(DECOMPOSE START)\n"); | |
239 | |
240 context->origin()->TryGuaranteeRangeRecursive(context); | |
241 | |
242 if (FLAG_log_abcd) | |
243 PrintF(" ___ TryGuaranteeRangeRecursive(DECOMPOSE END [%s])\n", | |
244 context->RangeSatisfied() ? "!" : "x"); | |
245 | |
246 context->swap_origin(base, offset, scale); | |
247 } | |
248 if (context->RangeSatisfied()) return; | |
249 | |
250 // Try to modify this to satisfy the constraint. | |
251 TryGuaranteeRangeInner(context); | |
252 | |
253 if (FLAG_log_abcd) { | |
254 PrintF(" >>> TryGuaranteeRangeRecursive("); | |
255 SimplyPrint(); | |
256 PrintF("): %s\n", context->RangeSatisfied() ? "TRUE" : "FALSE"); | |
257 } | |
258 } | |
259 | |
260 | |
261 HValue::RangeEvaluationContext::RangeEvaluationContext( | |
262 HValue* value, HValue* upper) | |
Jakob Kummerow
2013/03/11 11:55:02
for method/function declarations (as opposed to ca
| |
263 : lower_bound_(upper->block()->graph()->GetConstant0()), | |
264 lower_check_guarantee_(NULL), | |
265 origin_(value), | |
266 upper_bound_(upper), | |
267 upper_check_guarantee_(NULL), | |
268 offset_(0), scale_(0) { | |
Jakob Kummerow
2013/03/11 11:55:02
let's give each initializer its own line.
| |
269 } | |
270 | |
271 | |
272 HValue* HValue::RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { | |
Jakob Kummerow
2013/03/11 11:55:02
This method is simple enough to live in the .h fil
Massi
2013/03/13 15:58:14
But it needs to access HBoundsCheckBaseIndexInform
| |
273 return guarantee->IsBoundsCheckBaseIndexInformation() | |
274 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check() | |
275 : guarantee; | |
276 } | |
277 | |
278 | |
163 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { | 279 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { |
164 if (result > kMaxInt) { | 280 if (result > kMaxInt) { |
165 *overflow = true; | 281 *overflow = true; |
166 return kMaxInt; | 282 return kMaxInt; |
167 } | 283 } |
168 if (result < kMinInt) { | 284 if (result < kMinInt) { |
169 *overflow = true; | 285 *overflow = true; |
170 return kMinInt; | 286 return kMinInt; |
171 } | 287 } |
172 return static_cast<int32_t>(result); | 288 return static_cast<int32_t>(result); |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
775 if (other_operand == NULL) continue; | 891 if (other_operand == NULL) continue; |
776 HBasicBlock* other_block = other_operand->block(); | 892 HBasicBlock* other_block = other_operand->block(); |
777 if (cur_block == other_block) { | 893 if (cur_block == other_block) { |
778 if (!other_operand->IsPhi()) { | 894 if (!other_operand->IsPhi()) { |
779 HInstruction* cur = this->previous(); | 895 HInstruction* cur = this->previous(); |
780 while (cur != NULL) { | 896 while (cur != NULL) { |
781 if (cur == other_operand) break; | 897 if (cur == other_operand) break; |
782 cur = cur->previous(); | 898 cur = cur->previous(); |
783 } | 899 } |
784 // Must reach other operand in the same block! | 900 // Must reach other operand in the same block! |
901 | |
902 if (cur != other_operand) { | |
903 PrintF("\n !!! !!! !!! !!! !!! ASSERT([BLOCK %d]", | |
904 other_operand->block()->block_id()); | |
905 other_operand->SimplyPrint(); | |
906 PrintF(" used in index %d does not dominate [BLOCK %d]", | |
907 i, block()->block_id()); | |
908 SimplyPrint(); | |
909 PrintF(")\n"); | |
910 } | |
911 | |
785 ASSERT(cur == other_operand); | 912 ASSERT(cur == other_operand); |
786 } | 913 } |
787 } else { | 914 } else { |
788 // If the following assert fires, you may have forgotten an | 915 // If the following assert fires, you may have forgotten an |
789 // AddInstruction. | 916 // AddInstruction. |
790 ASSERT(other_block->Dominates(cur_block)); | 917 ASSERT(other_block->Dominates(cur_block)); |
791 } | 918 } |
792 } | 919 } |
793 | 920 |
794 // Verify that instructions that may have side-effects are followed | 921 // Verify that instructions that may have side-effects are followed |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
878 | 1005 |
879 void HBinaryCall::PrintDataTo(StringStream* stream) { | 1006 void HBinaryCall::PrintDataTo(StringStream* stream) { |
880 first()->PrintNameTo(stream); | 1007 first()->PrintNameTo(stream); |
881 stream->Add(" "); | 1008 stream->Add(" "); |
882 second()->PrintNameTo(stream); | 1009 second()->PrintNameTo(stream); |
883 stream->Add(" "); | 1010 stream->Add(" "); |
884 stream->Add("#%d", argument_count()); | 1011 stream->Add("#%d", argument_count()); |
885 } | 1012 } |
886 | 1013 |
887 | 1014 |
1015 void HBoundsCheck::TryGuaranteeRangeInner(RangeEvaluationContext* context) { | |
1016 if (FLAG_log_abcd) { | |
1017 PrintF(" +++ HBoundsCheck::TryGuaranteeRangeInner("); | |
1018 SimplyPrint(); | |
1019 PrintF(" [LOWER "); | |
1020 if (context->lower_check_satisfied()) { | |
1021 context->lower_check_guarantee()->SimplyPrint(); | |
1022 } else { | |
1023 PrintF("NULL"); | |
1024 } | |
1025 PrintF("] [UPPER "); | |
1026 if (context->upper_check_satisfied()) { | |
1027 context->upper_check_guarantee()->SimplyPrint(); | |
1028 } else { | |
1029 PrintF("NULL"); | |
1030 } | |
1031 PrintF("])\n"); | |
1032 } | |
1033 | |
1034 if (context->origin()->ActualValue() == base()->ActualValue() && | |
Jakob Kummerow
2013/03/11 11:55:02
nit: you can avoid one level of nested conditions
| |
1035 context->scale() >= scale()) { | |
1036 if (index_has_not_been_changed()) { | |
1037 if (offset() < context->offset()) { | |
1038 change_direction_ = 1; | |
Jakob Kummerow
2013/03/11 11:55:02
It doesn't seem right that we're always setting ch
| |
1039 } else if (offset() > context->offset()) { | |
1040 change_direction_ = -1; | |
1041 } | |
1042 } | |
1043 | |
1044 if (context->upper_bound() == length() && | |
1045 context->lower_check_satisfied() && | |
1046 context->lower_check_guarantee() != this && | |
1047 index_can_increase() && | |
1048 !context->upper_check_satisfied()) { | |
1049 if (offset() < context->offset()) { | |
Jakob Kummerow
2013/03/11 11:55:02
Since this condition doesn't have an else-branch,
| |
1050 | |
1051 if (FLAG_log_abcd) | |
1052 PrintF(" ___ HBoundsCheck::TryGuaranteeRangeInner(%s%d CHANGE UPPER(base %s%d[%s%d][%d]), offset %d (was %d), scale %d)\n", | |
1053 representation().Mnemonic(), id(), | |
1054 base()->representation().Mnemonic(), base()->id(), | |
1055 base()->ActualValue()->representation().Mnemonic(), base()->Actua lValue()->id(), | |
1056 change_direction_, context->offset(), offset(), scale()); | |
1057 | |
1058 offset_ = context->offset(); | |
1059 change_direction_ = 1; | |
Jakob Kummerow
2013/03/11 11:55:02
To make it more obvious that this is closely relat
| |
1060 context->set_upper_check_guarantee(this); | |
1061 } | |
1062 } else if (context->upper_check_satisfied() && | |
1063 context->upper_check_guarantee() != this && | |
1064 index_can_decrease() && | |
1065 !context->lower_check_satisfied()) { | |
1066 if (offset() > context->offset()) { | |
1067 | |
1068 if (FLAG_log_abcd) | |
1069 PrintF(" ___ HBoundsCheck::TryGuaranteeRangeInner(%s%d CHANGE LOWER(base %s%d[%s%d][%d]), offset %d (was %d), scale %d)\n", | |
1070 representation().Mnemonic(), id(), | |
1071 base()->representation().Mnemonic(), base()->id(), | |
1072 base()->ActualValue()->representation().Mnemonic(), base()->Actua lValue()->id(), | |
1073 change_direction_, context->offset(), offset(), scale()); | |
1074 | |
1075 offset_ = context->offset(); | |
1076 change_direction_ = -1; | |
1077 context->set_lower_check_guarantee(this); | |
1078 } | |
1079 } | |
1080 } | |
1081 } | |
1082 | |
1083 | |
1084 void HBoundsCheck::ApplyIndexChange() { | |
1085 if (HasOriginalIndex() || skip_check()) return; | |
Jakob Kummerow
2013/03/11 11:55:02
HasOriginalIndex() potentially performs the "index
| |
1086 | |
1087 HValue* base_index = NULL; | |
Jakob Kummerow
2013/03/11 11:55:02
I think you mean index_base, index_offset, index_s
| |
1088 int base_offset = 0; | |
1089 int base_scale = 0; | |
1090 if (!index()->TryDecompose(&base_index, &base_offset, &base_scale)) return; | |
1091 | |
1092 ReplaceAllUsesWith(index()); | |
1093 | |
1094 HValue* current_index = base_index; | |
1095 int actual_offset = base_offset + offset(); | |
1096 int actual_scale = base_scale + scale(); | |
1097 | |
1098 if (actual_offset != 0) { | |
1099 HConstant* add_offset = new(block()->graph()->zone()) HConstant( | |
1100 actual_offset, index()->representation()); | |
1101 add_offset->InsertBefore(this); | |
1102 HAdd* add = new(block()->graph()->zone()) HAdd( | |
1103 block()->graph()->GetInvalidContext(), current_index, add_offset); | |
1104 add->InsertBefore(this); | |
1105 add->AssumeRepresentation(index()->representation()); | |
1106 current_index = add; | |
1107 } | |
1108 | |
1109 if (actual_scale != 0) { | |
1110 HConstant* sar_scale = new(block()->graph()->zone()) HConstant( | |
1111 actual_scale, index()->representation()); | |
1112 sar_scale->InsertBefore(this); | |
1113 HSar* sar = new(block()->graph()->zone()) HSar( | |
1114 block()->graph()->GetInvalidContext(), current_index, sar_scale); | |
1115 sar->InsertBefore(this); | |
1116 sar->AssumeRepresentation(index()->representation()); | |
1117 current_index = sar; | |
1118 } | |
1119 | |
1120 | |
1121 if (FLAG_log_abcd) | |
1122 PrintF("\n !!! !!! !!! HBoundsCheck::ApplyIndexChange(%s%d, index %s%d becomes ((%s%d + %d) >> %d)\n", | |
1123 representation().Mnemonic(), id(), | |
1124 index()->representation().Mnemonic(), index()->id(), | |
1125 current_index->representation().Mnemonic(), current_index->id(), | |
1126 offset(), scale()); | |
1127 | |
1128 SetOperandAt(0, current_index); | |
1129 | |
1130 PrintF(" "); | |
1131 | |
1132 base_ = NULL; | |
Jakob Kummerow
2013/03/11 11:55:02
Is it necessary to do this cleanup?
Massi
2013/03/13 15:58:14
In principle, no, but I don't like leaving meaning
Jakob Kummerow
2013/03/14 12:50:08
I disagree with this reasoning. Resetting those va
| |
1133 offset_ = 0; | |
1134 scale_ = 0; | |
1135 change_direction_ = 0; | |
1136 } | |
1137 | |
1138 | |
888 void HBoundsCheck::AddInformativeDefinitions() { | 1139 void HBoundsCheck::AddInformativeDefinitions() { |
889 // TODO(mmassi): Executing this code during AddInformativeDefinitions | 1140 // TODO(mmassi): Executing this code during AddInformativeDefinitions |
890 // is a hack. Move it to some other HPhase. | 1141 // is a hack. Move it to some other HPhase. |
891 if (index()->IsRelationTrue(NumericRelation::Ge(), | 1142 if (FLAG_new_abcd) { |
892 block()->graph()->GetConstant0()) && | 1143 |
893 index()->IsRelationTrue(NumericRelation::Lt(), length())) { | 1144 if (FLAG_log_abcd) { |
894 set_skip_check(true); | 1145 PrintF("\n +++ >>> >>> >>> HBoundsCheck::AddInformativeDefinitions[BLOCK %d] (", |
1146 block()->block_id()); | |
1147 SimplyPrint(); | |
1148 PrintF(") CHANGE FOR LENGTH %s%d\n", | |
1149 length()->representation().Mnemonic(), length()->id()); | |
1150 | |
1151 if (index()->TryGuaranteeRange(length())) { | |
Jakob Kummerow
2013/03/11 11:55:02
This should *not* be inside the if(FLAG_log_abcd)
| |
1152 set_skip_check(true); | |
1153 } | |
1154 } | |
1155 | |
1156 if (DetectCompoundIndex()) { | |
1157 HBoundsCheckBaseIndexInformation* base_index_info = | |
1158 new(block()->graph()->zone()) | |
1159 HBoundsCheckBaseIndexInformation(this); | |
1160 base_index_info->InsertAfter(this); | |
1161 } | |
1162 | |
1163 if (FLAG_log_abcd) { | |
1164 PrintF(" +++ <<< <<< <<< HBoundsCheck::AddInformativeDefinitions[BLOCK %d](" , | |
1165 block()->block_id()); | |
1166 SimplyPrint(); | |
1167 if (base() != index()) { | |
1168 PrintF("{base %s%d (actually %s%d)}", | |
1169 base()->representation().Mnemonic(), base()->id(), | |
1170 base()->ActualValue()->representation().Mnemonic(), base()->ActualV alue()->id()); | |
1171 } | |
1172 PrintF(") LENGTH %s%d CHANGE %s\n", | |
1173 length()->representation().Mnemonic(), length()->id(), | |
1174 skip_check() ? "TRUE" : "FALSE"); | |
1175 } | |
1176 | |
1177 } else { | |
1178 if (index()->IsRelationTrue(NumericRelation::Ge(), | |
1179 block()->graph()->GetConstant0()) && | |
1180 index()->IsRelationTrue(NumericRelation::Lt(), length())) { | |
1181 set_skip_check(true); | |
1182 } | |
895 } | 1183 } |
896 } | 1184 } |
897 | 1185 |
898 | 1186 |
899 bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation, | 1187 bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation, |
900 HValue* related_value) { | 1188 HValue* related_value, |
1189 int offset, | |
1190 int scale) { | |
901 if (related_value == length()) { | 1191 if (related_value == length()) { |
902 // A HBoundsCheck is smaller than the length it compared against. | 1192 // A HBoundsCheck is smaller than the length it compared against. |
903 return NumericRelation::Lt().Implies(relation); | 1193 return NumericRelation::Lt().CompoundImplies(relation, 0, 0, offset, scale); |
904 } else if (related_value == block()->graph()->GetConstant0()) { | 1194 } else if (related_value == block()->graph()->GetConstant0()) { |
905 // A HBoundsCheck is greater than or equal to zero. | 1195 // A HBoundsCheck is greater than or equal to zero. |
906 return NumericRelation::Ge().Implies(relation); | 1196 return NumericRelation::Ge().CompoundImplies(relation, 0, 0, offset, scale); |
907 } else { | 1197 } else { |
908 return false; | 1198 return false; |
909 } | 1199 } |
910 } | 1200 } |
911 | 1201 |
912 | 1202 |
913 void HBoundsCheck::PrintDataTo(StringStream* stream) { | 1203 void HBoundsCheck::PrintDataTo(StringStream* stream) { |
914 index()->PrintNameTo(stream); | 1204 index()->PrintNameTo(stream); |
915 stream->Add(" "); | 1205 stream->Add(" "); |
916 length()->PrintNameTo(stream); | 1206 length()->PrintNameTo(stream); |
1207 if (base() != NULL && (offset() != 0 || scale() != 0)) { | |
1208 stream->Add("base: (("); | |
Jakob Kummerow
2013/03/11 11:55:02
nit: you probably want to print a space first, i.e
| |
1209 if (base() != index()) { | |
1210 index()->PrintNameTo(stream); | |
1211 } else { | |
1212 stream->Add("index"); | |
1213 } | |
1214 stream->Add(" + %d) >> %d)", offset(), scale()); | |
1215 } | |
917 if (skip_check()) { | 1216 if (skip_check()) { |
918 stream->Add(" [DISABLED]"); | 1217 stream->Add(" [DISABLED]"); |
919 } | 1218 } |
920 } | 1219 } |
921 | 1220 |
922 | 1221 |
923 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { | 1222 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { |
924 ASSERT(CheckFlag(kFlexibleRepresentation)); | 1223 ASSERT(CheckFlag(kFlexibleRepresentation)); |
925 Representation r; | 1224 Representation r; |
926 if (key_mode_ == DONT_ALLOW_SMI_KEY || | 1225 if (key_mode_ == DONT_ALLOW_SMI_KEY || |
927 !length()->representation().IsTagged()) { | 1226 !length()->representation().IsTagged()) { |
928 r = Representation::Integer32(); | 1227 r = Representation::Integer32(); |
929 } else if (index()->representation().IsTagged() || | 1228 } else if (index()->representation().IsTagged() || |
930 (index()->ActualValue()->IsConstant() && | 1229 (index()->ActualValue()->IsConstant() && |
931 HConstant::cast(index()->ActualValue())->HasSmiValue())) { | 1230 HConstant::cast(index()->ActualValue())->HasSmiValue())) { |
932 // If the index is tagged, or a constant that holds a Smi, allow the length | 1231 // If the index is tagged, or a constant that holds a Smi, allow the length |
933 // to be tagged, since it is usually already tagged from loading it out of | 1232 // to be tagged, since it is usually already tagged from loading it out of |
934 // the length field of a JSArray. This allows for direct comparison without | 1233 // the length field of a JSArray. This allows for direct comparison without |
935 // untagging. | 1234 // untagging. |
936 r = Representation::Tagged(); | 1235 r = Representation::Tagged(); |
937 } else { | 1236 } else { |
938 r = Representation::Integer32(); | 1237 r = Representation::Integer32(); |
939 } | 1238 } |
940 UpdateRepresentation(r, h_infer, "boundscheck"); | 1239 UpdateRepresentation(r, h_infer, "boundscheck"); |
941 } | 1240 } |
942 | 1241 |
943 | 1242 |
1243 bool HBoundsCheckBaseIndexInformation::IsRelationTrueInternal( | |
1244 NumericRelation relation, | |
1245 HValue* related_value, | |
1246 int offset, | |
1247 int scale) { | |
1248 if (related_value == bounds_check()->length()) { | |
1249 return NumericRelation::Lt().CompoundImplies( | |
1250 relation, | |
1251 bounds_check()->offset(), bounds_check()->scale(), offset, scale); | |
1252 } else if (related_value == block()->graph()->GetConstant0()) { | |
1253 return NumericRelation::Ge().CompoundImplies( | |
1254 relation, | |
1255 bounds_check()->offset(), bounds_check()->scale(), offset, scale); | |
1256 } else { | |
1257 return false; | |
1258 } | |
1259 } | |
1260 | |
1261 | |
1262 void HBoundsCheckBaseIndexInformation::PrintDataTo(StringStream* stream) { | |
1263 stream->Add("base: "); | |
1264 base_index()->PrintNameTo(stream); | |
1265 stream->Add(", check: "); | |
1266 base_index()->PrintNameTo(stream); | |
1267 } | |
1268 | |
1269 | |
944 void HCallConstantFunction::PrintDataTo(StringStream* stream) { | 1270 void HCallConstantFunction::PrintDataTo(StringStream* stream) { |
945 if (IsApplyFunction()) { | 1271 if (IsApplyFunction()) { |
946 stream->Add("optimized apply "); | 1272 stream->Add("optimized apply "); |
947 } else { | 1273 } else { |
948 stream->Add("%o ", function()->shared()->DebugName()); | 1274 stream->Add("%o ", function()->shared()->DebugName()); |
949 } | 1275 } |
950 stream->Add("#%d", argument_count()); | 1276 stream->Add("#%d", argument_count()); |
951 } | 1277 } |
952 | 1278 |
953 | 1279 |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1597 HInductionVariableAnnotation::AddToGraph(this, | 1923 HInductionVariableAnnotation::AddToGraph(this, |
1598 relations[relation_index], | 1924 relations[relation_index], |
1599 other_operand_index); | 1925 other_operand_index); |
1600 } | 1926 } |
1601 } | 1927 } |
1602 } | 1928 } |
1603 } | 1929 } |
1604 } | 1930 } |
1605 | 1931 |
1606 | 1932 |
1607 bool HPhi::IsRelationTrueInternal(NumericRelation relation, HValue* other) { | 1933 bool HPhi::IsRelationTrueInternal( |
1934 NumericRelation relation, HValue* other, int offset, int scale) { | |
Jakob Kummerow
2013/03/11 11:55:02
for method/function declarations (as opposed to ca
| |
1608 if (CheckFlag(kNumericConstraintEvaluationInProgress)) return false; | 1935 if (CheckFlag(kNumericConstraintEvaluationInProgress)) return false; |
1609 | 1936 |
1610 SetFlag(kNumericConstraintEvaluationInProgress); | 1937 SetFlag(kNumericConstraintEvaluationInProgress); |
1611 bool result = true; | 1938 bool result = true; |
1612 for (int i = 0; i < OperandCount(); i++) { | 1939 for (int i = 0; i < OperandCount(); i++) { |
1613 // Skip OSR entry blocks | 1940 // Skip OSR entry blocks |
1614 if (OperandAt(i)->block()->is_osr_entry()) continue; | 1941 if (OperandAt(i)->block()->is_osr_entry()) continue; |
1615 | 1942 |
1616 if (!OperandAt(i)->IsRelationTrue(relation, other)) { | 1943 if (!OperandAt(i)->IsRelationTrue(relation, other, offset, scale)) { |
1617 result = false; | 1944 result = false; |
1618 break; | 1945 break; |
1619 } | 1946 } |
1620 } | 1947 } |
1621 ClearFlag(kNumericConstraintEvaluationInProgress); | 1948 ClearFlag(kNumericConstraintEvaluationInProgress); |
1622 | 1949 |
1623 return result; | 1950 return result; |
1624 } | 1951 } |
1625 | 1952 |
1626 | 1953 |
(...skipping 1473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3100 | 3427 |
3101 | 3428 |
3102 void HCheckFunction::Verify() { | 3429 void HCheckFunction::Verify() { |
3103 HInstruction::Verify(); | 3430 HInstruction::Verify(); |
3104 ASSERT(HasNoUses()); | 3431 ASSERT(HasNoUses()); |
3105 } | 3432 } |
3106 | 3433 |
3107 #endif | 3434 #endif |
3108 | 3435 |
3109 } } // namespace v8::internal | 3436 } } // namespace v8::internal |
OLD | NEW |