1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-osr.h"
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen.h"
862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// True iff. we are compiling for OSR and the statement is the entry.
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HOsrBuilder::HasOsrEntryAt(IterationStatement* statement) {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return statement->OsrEntryId() == builder_->current_info()->osr_ast_id();
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHBasicBlock* HOsrBuilder::BuildOsrLoopEntry(IterationStatement* statement) {
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(HasOsrEntryAt(statement));
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone = builder_->zone();
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* graph = builder_->graph();
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // only one OSR point per compile is allowed.
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(graph->osr() == NULL);
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // remember this builder as the one OSR builder in the graph.
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  graph->set_osr(this);
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* non_osr_entry = graph->CreateBasicBlock();
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  osr_entry_ = graph->CreateBasicBlock();
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* true_value = graph->GetConstantTrue();
34c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HBranch* test = builder_->New<HBranch>(true_value, ToBooleanHint::kNone,
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         non_osr_entry, osr_entry_);
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  builder_->FinishCurrentBlock(test);
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* loop_predecessor = graph->CreateBasicBlock();
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  builder_->Goto(non_osr_entry, loop_predecessor);
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  builder_->set_current_block(osr_entry_);
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  osr_entry_->set_osr_entry();
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId osr_entry_id = statement->OsrEntryId();
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnvironment *environment = builder_->environment();
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int first_expression_index = environment->first_expression_index();
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int length = environment->length();
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  osr_values_ = new(zone) ZoneList<HUnknownOSRValue*>(length, zone);
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < first_expression_index; ++i) {
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HUnknownOSRValue* osr_value
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        = builder_->Add<HUnknownOSRValue>(environment, i);
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment->Bind(i, osr_value);
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    osr_values_->Add(osr_value, zone);
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (first_expression_index != length) {
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment->Drop(length - first_expression_index);
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = first_expression_index; i < length; ++i) {
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HUnknownOSRValue* osr_value
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          = builder_->Add<HUnknownOSRValue>(environment, i);
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment->Push(osr_value);
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      osr_values_->Add(osr_value, zone);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unoptimized_frame_slots_ =
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment->local_count() + environment->push_count();
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Keep a copy of the old environment, since the OSR values need it
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to figure out where exactly they are located in the unoptimized frame.
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment = environment->Copy();
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  builder_->current_block()->UpdateEnvironment(environment);
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  builder_->Add<HSimulate>(osr_entry_id);
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  builder_->Add<HOsrEntry>(osr_entry_id);
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HContext* context = builder_->Add<HContext>();
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment->BindContext(context);
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  builder_->Goto(loop_predecessor);
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  loop_predecessor->SetJoinId(statement->EntryId());
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  builder_->set_current_block(loop_predecessor);
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create the final loop entry
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  osr_loop_entry_ = builder_->BuildLoopEntry();
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return osr_loop_entry_;
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOsrBuilder::FinishGraph() {
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // do nothing for now.
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HOsrBuilder::FinishOsrValues() {
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const ZoneList<HPhi*>* phis = osr_loop_entry_->phis();
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int j = 0; j < phis->length(); j++) {
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HPhi* phi = phis->at(j);
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (phi->HasMergedIndex()) {
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      osr_values_->at(phi->merged_index())->set_incoming_value(phi);
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
106