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

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

Issue 1823623002: [crankshaft] Delete unused Hydrogen-BCH code (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « src/crankshaft/hydrogen-instructions.h ('k') | src/crankshaft/ia32/lithium-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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/crankshaft/hydrogen-instructions.h" 5 #include "src/crankshaft/hydrogen-instructions.h"
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/base/safe_math.h" 8 #include "src/base/safe_math.h"
9 #include "src/crankshaft/hydrogen-infer-representation.h" 9 #include "src/crankshaft/hydrogen-infer-representation.h"
10 #include "src/double.h" 10 #include "src/double.h"
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 768
769 bool HInstruction::CanDeoptimize() { 769 bool HInstruction::CanDeoptimize() {
770 switch (opcode()) { 770 switch (opcode()) {
771 case HValue::kAbnormalExit: 771 case HValue::kAbnormalExit:
772 case HValue::kAccessArgumentsAt: 772 case HValue::kAccessArgumentsAt:
773 case HValue::kAllocate: 773 case HValue::kAllocate:
774 case HValue::kArgumentsElements: 774 case HValue::kArgumentsElements:
775 case HValue::kArgumentsLength: 775 case HValue::kArgumentsLength:
776 case HValue::kArgumentsObject: 776 case HValue::kArgumentsObject:
777 case HValue::kBlockEntry: 777 case HValue::kBlockEntry:
778 case HValue::kBoundsCheckBaseIndexInformation:
779 case HValue::kCallNewArray: 778 case HValue::kCallNewArray:
780 case HValue::kCapturedObject: 779 case HValue::kCapturedObject:
781 case HValue::kClassOfTestAndBranch: 780 case HValue::kClassOfTestAndBranch:
782 case HValue::kCompareGeneric: 781 case HValue::kCompareGeneric:
783 case HValue::kCompareHoleAndBranch: 782 case HValue::kCompareHoleAndBranch:
784 case HValue::kCompareMap: 783 case HValue::kCompareMap:
785 case HValue::kCompareNumericAndBranch: 784 case HValue::kCompareNumericAndBranch:
786 case HValue::kCompareObjectEqAndBranch: 785 case HValue::kCompareObjectEqAndBranch:
787 case HValue::kConstant: 786 case HValue::kConstant:
788 case HValue::kConstructDouble: 787 case HValue::kConstructDouble:
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 } 916 }
918 917
919 std::ostream& HInvokeFunction::PrintDataTo(std::ostream& os) const { // NOLINT 918 std::ostream& HInvokeFunction::PrintDataTo(std::ostream& os) const { // NOLINT
920 HBinaryCall::PrintDataTo(os); 919 HBinaryCall::PrintDataTo(os);
921 if (syntactic_tail_call_mode() == TailCallMode::kAllow) { 920 if (syntactic_tail_call_mode() == TailCallMode::kAllow) {
922 os << ", JSTailCall"; 921 os << ", JSTailCall";
923 } 922 }
924 return os; 923 return os;
925 } 924 }
926 925
927 void HBoundsCheck::ApplyIndexChange() {
928 if (skip_check()) return;
929
930 DecompositionResult decomposition;
931 bool index_is_decomposable = index()->TryDecompose(&decomposition);
932 if (index_is_decomposable) {
933 DCHECK(decomposition.base() == base());
934 if (decomposition.offset() == offset() &&
935 decomposition.scale() == scale()) return;
936 } else {
937 return;
938 }
939
940 ReplaceAllUsesWith(index());
941
942 HValue* current_index = decomposition.base();
943 int actual_offset = decomposition.offset() + offset();
944 int actual_scale = decomposition.scale() + scale();
945
946 HGraph* graph = block()->graph();
947 Isolate* isolate = graph->isolate();
948 Zone* zone = graph->zone();
949 HValue* context = graph->GetInvalidContext();
950 if (actual_offset != 0) {
951 HConstant* add_offset =
952 HConstant::New(isolate, zone, context, actual_offset);
953 add_offset->InsertBefore(this);
954 HInstruction* add =
955 HAdd::New(isolate, zone, context, current_index, add_offset);
956 add->InsertBefore(this);
957 add->AssumeRepresentation(index()->representation());
958 add->ClearFlag(kCanOverflow);
959 current_index = add;
960 }
961
962 if (actual_scale != 0) {
963 HConstant* sar_scale = HConstant::New(isolate, zone, context, actual_scale);
964 sar_scale->InsertBefore(this);
965 HInstruction* sar =
966 HSar::New(isolate, zone, context, current_index, sar_scale);
967 sar->InsertBefore(this);
968 sar->AssumeRepresentation(index()->representation());
969 current_index = sar;
970 }
971
972 SetOperandAt(0, current_index);
973
974 base_ = NULL;
975 offset_ = 0;
976 scale_ = 0;
977 }
978
979
980 std::ostream& HBoundsCheck::PrintDataTo(std::ostream& os) const { // NOLINT 926 std::ostream& HBoundsCheck::PrintDataTo(std::ostream& os) const { // NOLINT
981 os << NameOf(index()) << " " << NameOf(length()); 927 os << NameOf(index()) << " " << NameOf(length());
982 if (base() != NULL && (offset() != 0 || scale() != 0)) { 928 if (base() != NULL && (offset() != 0 || scale() != 0)) {
983 os << " base: (("; 929 os << " base: ((";
984 if (base() != index()) { 930 if (base() != index()) {
985 os << NameOf(index()); 931 os << NameOf(index());
986 } else { 932 } else {
987 os << "index"; 933 os << "index";
988 } 934 }
989 os << " + " << offset() << ") >> " << scale() << ")"; 935 os << " + " << offset() << ") >> " << scale() << ")";
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 } 971 }
1026 972
1027 // In case of Smi representation, clamp result to Smi::kMaxValue. 973 // In case of Smi representation, clamp result to Smi::kMaxValue.
1028 if (r.IsSmi()) result->ClampToSmi(); 974 if (r.IsSmi()) result->ClampToSmi();
1029 return result; 975 return result;
1030 } 976 }
1031 return HValue::InferRange(zone); 977 return HValue::InferRange(zone);
1032 } 978 }
1033 979
1034 980
1035 std::ostream& HBoundsCheckBaseIndexInformation::PrintDataTo(
1036 std::ostream& os) const { // NOLINT
1037 // TODO(svenpanne) This 2nd base_index() looks wrong...
1038 return os << "base: " << NameOf(base_index())
1039 << ", check: " << NameOf(base_index());
1040 }
1041
1042
1043 std::ostream& HCallWithDescriptor::PrintDataTo( 981 std::ostream& HCallWithDescriptor::PrintDataTo(
1044 std::ostream& os) const { // NOLINT 982 std::ostream& os) const { // NOLINT
1045 for (int i = 0; i < OperandCount(); i++) { 983 for (int i = 0; i < OperandCount(); i++) {
1046 os << NameOf(OperandAt(i)) << " "; 984 os << NameOf(OperandAt(i)) << " ";
1047 } 985 }
1048 os << "#" << argument_count(); 986 os << "#" << argument_count();
1049 if (syntactic_tail_call_mode() == TailCallMode::kAllow) { 987 if (syntactic_tail_call_mode() == TailCallMode::kAllow) {
1050 os << ", JSTailCall"; 988 os << ", JSTailCall";
1051 } 989 }
1052 return os; 990 return os;
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
1956 if (!b->CanBeZero()) { 1894 if (!b->CanBeZero()) {
1957 ClearFlag(HValue::kCanBeDivByZero); 1895 ClearFlag(HValue::kCanBeDivByZero);
1958 } 1896 }
1959 return result; 1897 return result;
1960 } else { 1898 } else {
1961 return HValue::InferRange(zone); 1899 return HValue::InferRange(zone);
1962 } 1900 }
1963 } 1901 }
1964 1902
1965 1903
1966 InductionVariableData* InductionVariableData::ExaminePhi(HPhi* phi) {
1967 if (phi->block()->loop_information() == NULL) return NULL;
1968 if (phi->OperandCount() != 2) return NULL;
1969 int32_t candidate_increment;
1970
1971 candidate_increment = ComputeIncrement(phi, phi->OperandAt(0));
1972 if (candidate_increment != 0) {
1973 return new(phi->block()->graph()->zone())
1974 InductionVariableData(phi, phi->OperandAt(1), candidate_increment);
1975 }
1976
1977 candidate_increment = ComputeIncrement(phi, phi->OperandAt(1));
1978 if (candidate_increment != 0) {
1979 return new(phi->block()->graph()->zone())
1980 InductionVariableData(phi, phi->OperandAt(0), candidate_increment);
1981 }
1982
1983 return NULL;
1984 }
1985
1986
1987 /*
1988 * This function tries to match the following patterns (and all the relevant
1989 * variants related to |, & and + being commutative):
1990 * base | constant_or_mask
1991 * base & constant_and_mask
1992 * (base + constant_offset) & constant_and_mask
1993 * (base - constant_offset) & constant_and_mask
1994 */
1995 void InductionVariableData::DecomposeBitwise(
1996 HValue* value,
1997 BitwiseDecompositionResult* result) {
1998 HValue* base = IgnoreOsrValue(value);
1999 result->base = value;
2000
2001 if (!base->representation().IsInteger32()) return;
2002
2003 if (base->IsBitwise()) {
2004 bool allow_offset = false;
2005 int32_t mask = 0;
2006
2007 HBitwise* bitwise = HBitwise::cast(base);
2008 if (bitwise->right()->IsInteger32Constant()) {
2009 mask = bitwise->right()->GetInteger32Constant();
2010 base = bitwise->left();
2011 } else if (bitwise->left()->IsInteger32Constant()) {
2012 mask = bitwise->left()->GetInteger32Constant();
2013 base = bitwise->right();
2014 } else {
2015 return;
2016 }
2017 if (bitwise->op() == Token::BIT_AND) {
2018 result->and_mask = mask;
2019 allow_offset = true;
2020 } else if (bitwise->op() == Token::BIT_OR) {
2021 result->or_mask = mask;
2022 } else {
2023 return;
2024 }
2025
2026 result->context = bitwise->context();
2027
2028 if (allow_offset) {
2029 if (base->IsAdd()) {
2030 HAdd* add = HAdd::cast(base);
2031 if (add->right()->IsInteger32Constant()) {
2032 base = add->left();
2033 } else if (add->left()->IsInteger32Constant()) {
2034 base = add->right();
2035 }
2036 } else if (base->IsSub()) {
2037 HSub* sub = HSub::cast(base);
2038 if (sub->right()->IsInteger32Constant()) {
2039 base = sub->left();
2040 }
2041 }
2042 }
2043
2044 result->base = base;
2045 }
2046 }
2047
2048
2049 void InductionVariableData::AddCheck(HBoundsCheck* check,
2050 int32_t upper_limit) {
2051 DCHECK(limit_validity() != NULL);
2052 if (limit_validity() != check->block() &&
2053 !limit_validity()->Dominates(check->block())) return;
2054 if (!phi()->block()->current_loop()->IsNestedInThisLoop(
2055 check->block()->current_loop())) return;
2056
2057 ChecksRelatedToLength* length_checks = checks();
2058 while (length_checks != NULL) {
2059 if (length_checks->length() == check->length()) break;
2060 length_checks = length_checks->next();
2061 }
2062 if (length_checks == NULL) {
2063 length_checks = new(check->block()->zone())
2064 ChecksRelatedToLength(check->length(), checks());
2065 checks_ = length_checks;
2066 }
2067
2068 length_checks->AddCheck(check, upper_limit);
2069 }
2070
2071
2072 void InductionVariableData::ChecksRelatedToLength::CloseCurrentBlock() {
2073 if (checks() != NULL) {
2074 InductionVariableCheck* c = checks();
2075 HBasicBlock* current_block = c->check()->block();
2076 while (c != NULL && c->check()->block() == current_block) {
2077 c->set_upper_limit(current_upper_limit_);
2078 c = c->next();
2079 }
2080 }
2081 }
2082
2083
2084 void InductionVariableData::ChecksRelatedToLength::UseNewIndexInCurrentBlock(
2085 Token::Value token,
2086 int32_t mask,
2087 HValue* index_base,
2088 HValue* context) {
2089 DCHECK(first_check_in_block() != NULL);
2090 HValue* previous_index = first_check_in_block()->index();
2091 DCHECK(context != NULL);
2092
2093 Zone* zone = index_base->block()->graph()->zone();
2094 Isolate* isolate = index_base->block()->graph()->isolate();
2095 set_added_constant(HConstant::New(isolate, zone, context, mask));
2096 if (added_index() != NULL) {
2097 added_constant()->InsertBefore(added_index());
2098 } else {
2099 added_constant()->InsertBefore(first_check_in_block());
2100 }
2101
2102 if (added_index() == NULL) {
2103 first_check_in_block()->ReplaceAllUsesWith(first_check_in_block()->index());
2104 HInstruction* new_index = HBitwise::New(isolate, zone, context, token,
2105 index_base, added_constant());
2106 DCHECK(new_index->IsBitwise());
2107 new_index->ClearAllSideEffects();
2108 new_index->AssumeRepresentation(Representation::Integer32());
2109 set_added_index(HBitwise::cast(new_index));
2110 added_index()->InsertBefore(first_check_in_block());
2111 }
2112 DCHECK(added_index()->op() == token);
2113
2114 added_index()->SetOperandAt(1, index_base);
2115 added_index()->SetOperandAt(2, added_constant());
2116 first_check_in_block()->SetOperandAt(0, added_index());
2117 if (previous_index->HasNoUses()) {
2118 previous_index->DeleteAndReplaceWith(NULL);
2119 }
2120 }
2121
2122 void InductionVariableData::ChecksRelatedToLength::AddCheck(
2123 HBoundsCheck* check,
2124 int32_t upper_limit) {
2125 BitwiseDecompositionResult decomposition;
2126 InductionVariableData::DecomposeBitwise(check->index(), &decomposition);
2127
2128 if (first_check_in_block() == NULL ||
2129 first_check_in_block()->block() != check->block()) {
2130 CloseCurrentBlock();
2131
2132 first_check_in_block_ = check;
2133 set_added_index(NULL);
2134 set_added_constant(NULL);
2135 current_and_mask_in_block_ = decomposition.and_mask;
2136 current_or_mask_in_block_ = decomposition.or_mask;
2137 current_upper_limit_ = upper_limit;
2138
2139 InductionVariableCheck* new_check = new(check->block()->graph()->zone())
2140 InductionVariableCheck(check, checks_, upper_limit);
2141 checks_ = new_check;
2142 return;
2143 }
2144
2145 if (upper_limit > current_upper_limit()) {
2146 current_upper_limit_ = upper_limit;
2147 }
2148
2149 if (decomposition.and_mask != 0 &&
2150 current_or_mask_in_block() == 0) {
2151 if (current_and_mask_in_block() == 0 ||
2152 decomposition.and_mask > current_and_mask_in_block()) {
2153 UseNewIndexInCurrentBlock(Token::BIT_AND,
2154 decomposition.and_mask,
2155 decomposition.base,
2156 decomposition.context);
2157 current_and_mask_in_block_ = decomposition.and_mask;
2158 }
2159 check->set_skip_check();
2160 }
2161 if (current_and_mask_in_block() == 0) {
2162 if (decomposition.or_mask > current_or_mask_in_block()) {
2163 UseNewIndexInCurrentBlock(Token::BIT_OR,
2164 decomposition.or_mask,
2165 decomposition.base,
2166 decomposition.context);
2167 current_or_mask_in_block_ = decomposition.or_mask;
2168 }
2169 check->set_skip_check();
2170 }
2171
2172 if (!check->skip_check()) {
2173 InductionVariableCheck* new_check = new(check->block()->graph()->zone())
2174 InductionVariableCheck(check, checks_, upper_limit);
2175 checks_ = new_check;
2176 }
2177 }
2178
2179
2180 /*
2181 * This method detects if phi is an induction variable, with phi_operand as
2182 * its "incremented" value (the other operand would be the "base" value).
2183 *
2184 * It cheks is phi_operand has the form "phi + constant".
2185 * If yes, the constant is the increment that the induction variable gets at
2186 * every loop iteration.
2187 * Otherwise it returns 0.
2188 */
2189 int32_t InductionVariableData::ComputeIncrement(HPhi* phi,
2190 HValue* phi_operand) {
2191 if (!phi_operand->representation().IsSmiOrInteger32()) return 0;
2192
2193 if (phi_operand->IsAdd()) {
2194 HAdd* operation = HAdd::cast(phi_operand);
2195 if (operation->left() == phi &&
2196 operation->right()->IsInteger32Constant()) {
2197 return operation->right()->GetInteger32Constant();
2198 } else if (operation->right() == phi &&
2199 operation->left()->IsInteger32Constant()) {
2200 return operation->left()->GetInteger32Constant();
2201 }
2202 } else if (phi_operand->IsSub()) {
2203 HSub* operation = HSub::cast(phi_operand);
2204 if (operation->left() == phi &&
2205 operation->right()->IsInteger32Constant()) {
2206 int constant = operation->right()->GetInteger32Constant();
2207 if (constant == kMinInt) return 0;
2208 return -constant;
2209 }
2210 }
2211
2212 return 0;
2213 }
2214
2215
2216 /*
2217 * Swaps the information in "update" with the one contained in "this".
2218 * The swapping is important because this method is used while doing a
2219 * dominator tree traversal, and "update" will retain the old data that
2220 * will be restored while backtracking.
2221 */
2222 void InductionVariableData::UpdateAdditionalLimit(
2223 InductionVariableLimitUpdate* update) {
2224 DCHECK(update->updated_variable == this);
2225 if (update->limit_is_upper) {
2226 swap(&additional_upper_limit_, &update->limit);
2227 swap(&additional_upper_limit_is_included_, &update->limit_is_included);
2228 } else {
2229 swap(&additional_lower_limit_, &update->limit);
2230 swap(&additional_lower_limit_is_included_, &update->limit_is_included);
2231 }
2232 }
2233
2234
2235 int32_t InductionVariableData::ComputeUpperLimit(int32_t and_mask,
2236 int32_t or_mask) {
2237 // Should be Smi::kMaxValue but it must fit 32 bits; lower is safe anyway.
2238 const int32_t MAX_LIMIT = 1 << 30;
2239
2240 int32_t result = MAX_LIMIT;
2241
2242 if (limit() != NULL &&
2243 limit()->IsInteger32Constant()) {
2244 int32_t limit_value = limit()->GetInteger32Constant();
2245 if (!limit_included()) {
2246 limit_value--;
2247 }
2248 if (limit_value < result) result = limit_value;
2249 }
2250
2251 if (additional_upper_limit() != NULL &&
2252 additional_upper_limit()->IsInteger32Constant()) {
2253 int32_t limit_value = additional_upper_limit()->GetInteger32Constant();
2254 if (!additional_upper_limit_is_included()) {
2255 limit_value--;
2256 }
2257 if (limit_value < result) result = limit_value;
2258 }
2259
2260 if (and_mask > 0 && and_mask < MAX_LIMIT) {
2261 if (and_mask < result) result = and_mask;
2262 return result;
2263 }
2264
2265 // Add the effect of the or_mask.
2266 result |= or_mask;
2267
2268 return result >= MAX_LIMIT ? kNoLimit : result;
2269 }
2270
2271
2272 HValue* InductionVariableData::IgnoreOsrValue(HValue* v) {
2273 if (!v->IsPhi()) return v;
2274 HPhi* phi = HPhi::cast(v);
2275 if (phi->OperandCount() != 2) return v;
2276 if (phi->OperandAt(0)->block()->is_osr_entry()) {
2277 return phi->OperandAt(1);
2278 } else if (phi->OperandAt(1)->block()->is_osr_entry()) {
2279 return phi->OperandAt(0);
2280 } else {
2281 return v;
2282 }
2283 }
2284
2285
2286 InductionVariableData* InductionVariableData::GetInductionVariableData(
2287 HValue* v) {
2288 v = IgnoreOsrValue(v);
2289 if (v->IsPhi()) {
2290 return HPhi::cast(v)->induction_variable_data();
2291 }
2292 return NULL;
2293 }
2294
2295
2296 /*
2297 * Check if a conditional branch to "current_branch" with token "token" is
2298 * the branch that keeps the induction loop running (and, conversely, will
2299 * terminate it if the "other_branch" is taken).
2300 *
2301 * Three conditions must be met:
2302 * - "current_branch" must be in the induction loop.
2303 * - "other_branch" must be out of the induction loop.
2304 * - "token" and the induction increment must be "compatible": the token should
2305 * be a condition that keeps the execution inside the loop until the limit is
2306 * reached.
2307 */
2308 bool InductionVariableData::CheckIfBranchIsLoopGuard(
2309 Token::Value token,
2310 HBasicBlock* current_branch,
2311 HBasicBlock* other_branch) {
2312 if (!phi()->block()->current_loop()->IsNestedInThisLoop(
2313 current_branch->current_loop())) {
2314 return false;
2315 }
2316
2317 if (phi()->block()->current_loop()->IsNestedInThisLoop(
2318 other_branch->current_loop())) {
2319 return false;
2320 }
2321
2322 if (increment() > 0 && (token == Token::LT || token == Token::LTE)) {
2323 return true;
2324 }
2325 if (increment() < 0 && (token == Token::GT || token == Token::GTE)) {
2326 return true;
2327 }
2328 if (Token::IsInequalityOp(token) && (increment() == 1 || increment() == -1)) {
2329 return true;
2330 }
2331
2332 return false;
2333 }
2334
2335
2336 void InductionVariableData::ComputeLimitFromPredecessorBlock(
2337 HBasicBlock* block,
2338 LimitFromPredecessorBlock* result) {
2339 if (block->predecessors()->length() != 1) return;
2340 HBasicBlock* predecessor = block->predecessors()->at(0);
2341 HInstruction* end = predecessor->last();
2342
2343 if (!end->IsCompareNumericAndBranch()) return;
2344 HCompareNumericAndBranch* branch = HCompareNumericAndBranch::cast(end);
2345
2346 Token::Value token = branch->token();
2347 if (!Token::IsArithmeticCompareOp(token)) return;
2348
2349 HBasicBlock* other_target;
2350 if (block == branch->SuccessorAt(0)) {
2351 other_target = branch->SuccessorAt(1);
2352 } else {
2353 other_target = branch->SuccessorAt(0);
2354 token = Token::NegateCompareOp(token);
2355 DCHECK(block == branch->SuccessorAt(1));
2356 }
2357
2358 InductionVariableData* data;
2359
2360 data = GetInductionVariableData(branch->left());
2361 HValue* limit = branch->right();
2362 if (data == NULL) {
2363 data = GetInductionVariableData(branch->right());
2364 token = Token::ReverseCompareOp(token);
2365 limit = branch->left();
2366 }
2367
2368 if (data != NULL) {
2369 result->variable = data;
2370 result->token = token;
2371 result->limit = limit;
2372 result->other_target = other_target;
2373 }
2374 }
2375
2376
2377 /*
2378 * Compute the limit that is imposed on an induction variable when entering
2379 * "block" (if any).
2380 * If the limit is the "proper" induction limit (the one that makes the loop
2381 * terminate when the induction variable reaches it) it is stored directly in
2382 * the induction variable data.
2383 * Otherwise the limit is written in "additional_limit" and the method
2384 * returns true.
2385 */
2386 bool InductionVariableData::ComputeInductionVariableLimit(
2387 HBasicBlock* block,
2388 InductionVariableLimitUpdate* additional_limit) {
2389 LimitFromPredecessorBlock limit;
2390 ComputeLimitFromPredecessorBlock(block, &limit);
2391 if (!limit.LimitIsValid()) return false;
2392
2393 if (limit.variable->CheckIfBranchIsLoopGuard(limit.token,
2394 block,
2395 limit.other_target)) {
2396 limit.variable->limit_ = limit.limit;
2397 limit.variable->limit_included_ = limit.LimitIsIncluded();
2398 limit.variable->limit_validity_ = block;
2399 limit.variable->induction_exit_block_ = block->predecessors()->at(0);
2400 limit.variable->induction_exit_target_ = limit.other_target;
2401 return false;
2402 } else {
2403 additional_limit->updated_variable = limit.variable;
2404 additional_limit->limit = limit.limit;
2405 additional_limit->limit_is_upper = limit.LimitIsUpper();
2406 additional_limit->limit_is_included = limit.LimitIsIncluded();
2407 return true;
2408 }
2409 }
2410
2411
2412 Range* HMathMinMax::InferRange(Zone* zone) { 1904 Range* HMathMinMax::InferRange(Zone* zone) {
2413 if (representation().IsSmiOrInteger32()) { 1905 if (representation().IsSmiOrInteger32()) {
2414 Range* a = left()->range(); 1906 Range* a = left()->range();
2415 Range* b = right()->range(); 1907 Range* b = right()->range();
2416 Range* res = a->Copy(zone); 1908 Range* res = a->Copy(zone);
2417 if (operation_ == kMathMax) { 1909 if (operation_ == kMathMax) {
2418 res->CombinedMax(b); 1910 res->CombinedMax(b);
2419 } else { 1911 } else {
2420 DCHECK(operation_ == kMathMin); 1912 DCHECK(operation_ == kMathMin);
2421 res->CombinedMin(b); 1913 res->CombinedMin(b);
(...skipping 2215 matching lines...) Expand 10 before | Expand all | Expand 10 after
4637 case HObjectAccess::kExternalMemory: 4129 case HObjectAccess::kExternalMemory:
4638 os << "[external-memory]"; 4130 os << "[external-memory]";
4639 break; 4131 break;
4640 } 4132 }
4641 4133
4642 return os << "@" << access.offset(); 4134 return os << "@" << access.offset();
4643 } 4135 }
4644 4136
4645 } // namespace internal 4137 } // namespace internal
4646 } // namespace v8 4138 } // namespace v8
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen-instructions.h ('k') | src/crankshaft/ia32/lithium-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698