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