| 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/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
| 6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
| 7 #include "src/compiler/js-operator.h" | 7 #include "src/compiler/js-operator.h" |
| 8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" |
| 9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
| 10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 }; | 245 }; |
| 246 | 246 |
| 247 | 247 |
| 248 class Typer::RunVisitor : public Typer::Visitor { | 248 class Typer::RunVisitor : public Typer::Visitor { |
| 249 public: | 249 public: |
| 250 explicit RunVisitor(Typer* typer) | 250 explicit RunVisitor(Typer* typer) |
| 251 : Visitor(typer), | 251 : Visitor(typer), |
| 252 redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} | 252 redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} |
| 253 | 253 |
| 254 GenericGraphVisit::Control Post(Node* node) { | 254 GenericGraphVisit::Control Post(Node* node) { |
| 255 if (node->op()->ValueOutputCount() > 0 && !NodeProperties::IsTyped(node)) { | 255 if (node->op()->ValueOutputCount() > 0) { |
| 256 Bounds bounds = TypeNode(node); | 256 Bounds bounds = TypeNode(node); |
| 257 NodeProperties::SetBounds(node, bounds); | 257 NodeProperties::SetBounds(node, bounds); |
| 258 // Remember incompletely typed nodes for least fixpoint iteration. | 258 // Remember incompletely typed nodes for least fixpoint iteration. |
| 259 if (!NodeProperties::AllValueInputsAreTyped(node)) redo.insert(node); | 259 if (!NodeProperties::AllValueInputsAreTyped(node)) redo.insert(node); |
| 260 } | 260 } |
| 261 return GenericGraphVisit::CONTINUE; | 261 return GenericGraphVisit::CONTINUE; |
| 262 } | 262 } |
| 263 | 263 |
| 264 NodeSet redo; | 264 NodeSet redo; |
| 265 }; | 265 }; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 284 } | 284 } |
| 285 | 285 |
| 286 GenericGraphVisit::Control Post(Node* node) { | 286 GenericGraphVisit::Control Post(Node* node) { |
| 287 return GenericGraphVisit::REENTER; | 287 return GenericGraphVisit::REENTER; |
| 288 } | 288 } |
| 289 }; | 289 }; |
| 290 | 290 |
| 291 | 291 |
| 292 class Typer::WidenVisitor : public Typer::Visitor { | 292 class Typer::WidenVisitor : public Typer::Visitor { |
| 293 public: | 293 public: |
| 294 explicit WidenVisitor(Typer* typer) : Visitor(typer) {} | 294 explicit WidenVisitor(Typer* typer) |
| 295 : Visitor(typer), |
| 296 local_zone_(zone()->isolate()), |
| 297 enabled_(graph()->NodeCount(), true, &local_zone_), |
| 298 queue_(&local_zone_) {} |
| 295 | 299 |
| 296 GenericGraphVisit::Control Pre(Node* node) { | 300 void Run(NodeSet* nodes) { |
| 297 if (node->op()->ValueOutputCount() > 0) { | 301 // Queue all the roots. |
| 298 Bounds previous = BoundsOrNone(node); | 302 for (Node* node : *nodes) { |
| 299 Bounds current = TypeNode(node); | 303 Queue(node); |
| 304 } |
| 300 | 305 |
| 301 // Speed up termination in the presence of range types: | 306 while (!queue_.empty()) { |
| 302 current.upper = Weaken(current.upper, previous.upper); | 307 Node* node = queue_.front(); |
| 303 current.lower = Weaken(current.lower, previous.lower); | 308 queue_.pop(); |
| 304 | 309 |
| 305 DCHECK(previous.lower->Is(current.lower)); | 310 if (node->op()->ValueOutputCount() > 0) { |
| 306 DCHECK(previous.upper->Is(current.upper)); | 311 // Enable future queuing (and thus re-typing) of this node. |
| 312 enabled_[node->id()] = true; |
| 307 | 313 |
| 308 NodeProperties::SetBounds(node, current); | 314 // Compute the new type. |
| 309 // Stop when nothing changed (but allow re-entry in case it does later). | 315 Bounds previous = BoundsOrNone(node); |
| 310 return previous.Narrows(current) && current.Narrows(previous) | 316 Bounds current = TypeNode(node); |
| 311 ? GenericGraphVisit::DEFER | 317 |
| 312 : GenericGraphVisit::REENTER; | 318 // Speed up termination in the presence of range types: |
| 313 } else { | 319 current.upper = Weaken(current.upper, previous.upper); |
| 314 return GenericGraphVisit::SKIP; | 320 current.lower = Weaken(current.lower, previous.lower); |
| 321 |
| 322 // Types should not get less precise. |
| 323 DCHECK(previous.lower->Is(current.lower)); |
| 324 DCHECK(previous.upper->Is(current.upper)); |
| 325 |
| 326 NodeProperties::SetBounds(node, current); |
| 327 // If something changed, push all uses into the queue. |
| 328 if (!(previous.Narrows(current) && current.Narrows(previous))) { |
| 329 for (Node* use : node->uses()) { |
| 330 Queue(use); |
| 331 } |
| 332 } |
| 333 } |
| 334 // If there is no value output, we deliberately leave the node disabled |
| 335 // for queuing - there is no need to type it. |
| 315 } | 336 } |
| 316 } | 337 } |
| 317 | 338 |
| 318 GenericGraphVisit::Control Post(Node* node) { | 339 void Queue(Node* node) { |
| 319 return GenericGraphVisit::REENTER; | 340 // If the node is enabled for queuing, push it to the queue and disable it |
| 341 // (to avoid queuing it multiple times). |
| 342 if (enabled_[node->id()]) { |
| 343 queue_.push(node); |
| 344 enabled_[node->id()] = false; |
| 345 } |
| 320 } | 346 } |
| 347 |
| 348 private: |
| 349 Zone local_zone_; |
| 350 BoolVector enabled_; |
| 351 ZoneQueue<Node*> queue_; |
| 321 }; | 352 }; |
| 322 | 353 |
| 323 | 354 |
| 324 void Typer::Run() { | 355 void Typer::Run() { |
| 325 RunVisitor typing(this); | 356 RunVisitor typing(this); |
| 326 graph_->VisitNodeInputsFromEnd(&typing); | 357 graph_->VisitNodeInputsFromEnd(&typing); |
| 327 // Find least fixpoint. | 358 // Find least fixpoint. |
| 328 WidenVisitor widen(this); | 359 WidenVisitor widen(this); |
| 329 for (NodeSetIter it = typing.redo.begin(); it != typing.redo.end(); ++it) { | 360 widen.Run(&typing.redo); |
| 330 graph_->VisitNodeUsesFrom(*it, &widen); | |
| 331 } | |
| 332 } | 361 } |
| 333 | 362 |
| 334 | 363 |
| 335 void Typer::Narrow(Node* start) { | 364 void Typer::Narrow(Node* start) { |
| 336 NarrowVisitor typing(this); | 365 NarrowVisitor typing(this); |
| 337 graph_->VisitNodeUsesFrom(start, &typing); | 366 graph_->VisitNodeUsesFrom(start, &typing); |
| 338 } | 367 } |
| 339 | 368 |
| 340 | 369 |
| 341 void Typer::Decorator::Decorate(Node* node) { | 370 void Typer::Decorator::Decorate(Node* node) { |
| (...skipping 1537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1879 return typer_->float64_array_fun_; | 1908 return typer_->float64_array_fun_; |
| 1880 } | 1909 } |
| 1881 } | 1910 } |
| 1882 } | 1911 } |
| 1883 return Type::Constant(value, zone()); | 1912 return Type::Constant(value, zone()); |
| 1884 } | 1913 } |
| 1885 | 1914 |
| 1886 } | 1915 } |
| 1887 } | 1916 } |
| 1888 } // namespace v8::internal::compiler | 1917 } // namespace v8::internal::compiler |
| OLD | NEW |