| OLD | NEW | 
|     1 // Copyright 2014 the V8 project authors. All rights reserved. |     1 // Copyright 2014 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/compiler/typer.h" |     5 #include "src/compiler/typer.h" | 
|     6  |     6  | 
|     7 #include <iomanip> |     7 #include <iomanip> | 
|     8  |     8  | 
|     9 #include "src/base/flags.h" |     9 #include "src/base/flags.h" | 
|    10 #include "src/bootstrapper.h" |    10 #include "src/bootstrapper.h" | 
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   644   // the increment, just return the initial value's type. |   644   // the increment, just return the initial value's type. | 
|   645   if (!initial_type->IsInhabited() || !increment_type->IsInhabited()) { |   645   if (!initial_type->IsInhabited() || !increment_type->IsInhabited()) { | 
|   646     return initial_type; |   646     return initial_type; | 
|   647   } |   647   } | 
|   648  |   648  | 
|   649   // Now process the bounds. |   649   // Now process the bounds. | 
|   650   auto res = induction_vars_->induction_variables().find(node->id()); |   650   auto res = induction_vars_->induction_variables().find(node->id()); | 
|   651   DCHECK(res != induction_vars_->induction_variables().end()); |   651   DCHECK(res != induction_vars_->induction_variables().end()); | 
|   652   InductionVariable* induction_var = res->second; |   652   InductionVariable* induction_var = res->second; | 
|   653  |   653  | 
 |   654   InductionVariable::ArithmeticType arithmetic_type = induction_var->Type(); | 
 |   655  | 
|   654   double min = -V8_INFINITY; |   656   double min = -V8_INFINITY; | 
|   655   double max = V8_INFINITY; |   657   double max = V8_INFINITY; | 
|   656   if (increment_type->Min() >= 0) { |   658  | 
 |   659   double increment_min; | 
 |   660   double increment_max; | 
 |   661   if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) { | 
 |   662     increment_min = increment_type->Min(); | 
 |   663     increment_max = increment_type->Max(); | 
 |   664   } else { | 
 |   665     DCHECK(arithmetic_type == InductionVariable::ArithmeticType::kSubtraction); | 
 |   666     increment_min = -increment_type->Max(); | 
 |   667     increment_max = -increment_type->Min(); | 
 |   668   } | 
 |   669  | 
 |   670   if (increment_min >= 0) { | 
 |   671     // increasing sequence | 
|   657     min = initial_type->Min(); |   672     min = initial_type->Min(); | 
|   658     for (auto bound : induction_var->upper_bounds()) { |   673     for (auto bound : induction_var->upper_bounds()) { | 
|   659       Type* bound_type = TypeOrNone(bound.bound); |   674       Type* bound_type = TypeOrNone(bound.bound); | 
|   660       // If the type is not an integer, just skip the bound. |   675       // If the type is not an integer, just skip the bound. | 
|   661       if (!bound_type->Is(typer_->cache_.kInteger)) continue; |   676       if (!bound_type->Is(typer_->cache_.kInteger)) continue; | 
|   662       // If the type is not inhabited, then we can take the initial value. |   677       // If the type is not inhabited, then we can take the initial value. | 
|   663       if (!bound_type->IsInhabited()) { |   678       if (!bound_type->IsInhabited()) { | 
|   664         max = initial_type->Max(); |   679         max = initial_type->Max(); | 
|   665         break; |   680         break; | 
|   666       } |   681       } | 
|   667       double bound_max = bound_type->Max(); |   682       double bound_max = bound_type->Max(); | 
|   668       if (bound.kind == InductionVariable::kStrict) { |   683       if (bound.kind == InductionVariable::kStrict) { | 
|   669         bound_max -= 1; |   684         bound_max -= 1; | 
|   670       } |   685       } | 
|   671       max = std::min(max, bound_max + increment_type->Max()); |   686       max = std::min(max, bound_max + increment_max); | 
|   672     } |   687     } | 
|   673     // The upper bound must be at least the initial value's upper bound. |   688     // The upper bound must be at least the initial value's upper bound. | 
|   674     max = std::max(max, initial_type->Max()); |   689     max = std::max(max, initial_type->Max()); | 
|   675   } else if (increment_type->Max() <= 0) { |   690   } else if (increment_max <= 0) { | 
 |   691     // decreasing sequence | 
|   676     max = initial_type->Max(); |   692     max = initial_type->Max(); | 
|   677     for (auto bound : induction_var->lower_bounds()) { |   693     for (auto bound : induction_var->lower_bounds()) { | 
|   678       Type* bound_type = TypeOrNone(bound.bound); |   694       Type* bound_type = TypeOrNone(bound.bound); | 
|   679       // If the type is not an integer, just skip the bound. |   695       // If the type is not an integer, just skip the bound. | 
|   680       if (!bound_type->Is(typer_->cache_.kInteger)) continue; |   696       if (!bound_type->Is(typer_->cache_.kInteger)) continue; | 
|   681       // If the type is not inhabited, then we can take the initial value. |   697       // If the type is not inhabited, then we can take the initial value. | 
|   682       if (!bound_type->IsInhabited()) { |   698       if (!bound_type->IsInhabited()) { | 
|   683         min = initial_type->Min(); |   699         min = initial_type->Min(); | 
|   684         break; |   700         break; | 
|   685       } |   701       } | 
|   686       double bound_min = bound_type->Min(); |   702       double bound_min = bound_type->Min(); | 
|   687       if (bound.kind == InductionVariable::kStrict) { |   703       if (bound.kind == InductionVariable::kStrict) { | 
|   688         bound_min += 1; |   704         bound_min += 1; | 
|   689       } |   705       } | 
|   690       min = std::max(min, bound_min + increment_type->Min()); |   706       min = std::max(min, bound_min + increment_min); | 
|   691     } |   707     } | 
|   692     // The lower bound must be at most the initial value's lower bound. |   708     // The lower bound must be at most the initial value's lower bound. | 
|   693     min = std::min(min, initial_type->Min()); |   709     min = std::min(min, initial_type->Min()); | 
|   694   } else { |   710   } else { | 
|   695     // Shortcut: If the increment can be both positive and negative, |   711     // Shortcut: If the increment can be both positive and negative, | 
|   696     // the variable can go arbitrarily far, so just return integer. |   712     // the variable can go arbitrarily far, so just return integer. | 
|   697     return typer_->cache_.kInteger; |   713     return typer_->cache_.kInteger; | 
|   698   } |   714   } | 
|   699   if (FLAG_trace_turbo_loop) { |   715   if (FLAG_trace_turbo_loop) { | 
|   700     OFStream os(stdout); |   716     OFStream os(stdout); | 
|   701     os << std::setprecision(10); |   717     os << std::setprecision(10); | 
|   702     os << "Loop (" << NodeProperties::GetControlInput(node)->id() |   718     os << "Loop (" << NodeProperties::GetControlInput(node)->id() | 
|   703        << ") variable bounds for phi " << node->id() << ": (" << min << ", " |   719        << ") variable bounds in " | 
|   704        << max << ")\n"; |   720        << (arithmetic_type == InductionVariable::ArithmeticType::kAddition | 
 |   721                ? "addition" | 
 |   722                : "subtraction") | 
 |   723        << " for phi " << node->id() << ": (" << min << ", " << max << ")\n"; | 
|   705   } |   724   } | 
|   706   return Type::Range(min, max, typer_->zone()); |   725   return Type::Range(min, max, typer_->zone()); | 
|   707 } |   726 } | 
|   708  |   727  | 
|   709 Type* Typer::Visitor::TypeEffectPhi(Node* node) { |   728 Type* Typer::Visitor::TypeEffectPhi(Node* node) { | 
|   710   UNREACHABLE(); |   729   UNREACHABLE(); | 
|   711   return nullptr; |   730   return nullptr; | 
|   712 } |   731 } | 
|   713  |   732  | 
|   714 Type* Typer::Visitor::TypeLoopExit(Node* node) { |   733 Type* Typer::Visitor::TypeLoopExit(Node* node) { | 
| (...skipping 1606 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2321   } |  2340   } | 
|  2322   if (Type::IsInteger(*value)) { |  2341   if (Type::IsInteger(*value)) { | 
|  2323     return Type::Range(value->Number(), value->Number(), zone()); |  2342     return Type::Range(value->Number(), value->Number(), zone()); | 
|  2324   } |  2343   } | 
|  2325   return Type::Constant(value, zone()); |  2344   return Type::Constant(value, zone()); | 
|  2326 } |  2345 } | 
|  2327  |  2346  | 
|  2328 }  // namespace compiler |  2347 }  // namespace compiler | 
|  2329 }  // namespace internal |  2348 }  // namespace internal | 
|  2330 }  // namespace v8 |  2349 }  // namespace v8 | 
| OLD | NEW |