Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 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 |