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