Factor out OSR-related graph-building functionality from hydrogen.cc.
BUG= Review URL: https://codereview.chromium.org/18496002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15488 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
fea5ebe90f
commit
bddf08b0b1
123
src/hydrogen-osr.cc
Normal file
123
src/hydrogen-osr.cc
Normal file
@ -0,0 +1,123 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "hydrogen.h"
|
||||
#include "hydrogen-osr.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// True iff. we are compiling for OSR and the statement is the entry.
|
||||
bool HOsrBuilder::HasOsrEntryAt(IterationStatement* statement) {
|
||||
return statement->OsrEntryId() == builder_->current_info()->osr_ast_id();
|
||||
}
|
||||
|
||||
|
||||
// Build a new loop header block and set it as the current block.
|
||||
HBasicBlock *HOsrBuilder::BuildLoopEntry() {
|
||||
HBasicBlock* loop_entry = builder_->CreateLoopHeaderBlock();
|
||||
builder_->current_block()->Goto(loop_entry);
|
||||
builder_->set_current_block(loop_entry);
|
||||
return loop_entry;
|
||||
}
|
||||
|
||||
|
||||
HBasicBlock* HOsrBuilder::BuildPossibleOsrLoopEntry(
|
||||
IterationStatement* statement) {
|
||||
// Check if there is an OSR here first.
|
||||
if (!HasOsrEntryAt(statement)) return BuildLoopEntry();
|
||||
|
||||
Zone* zone = builder_->zone();
|
||||
HGraph* graph = builder_->graph();
|
||||
|
||||
// only one OSR point per compile is allowed.
|
||||
ASSERT(graph->osr() == NULL);
|
||||
|
||||
// remember this builder as the one OSR builder in the graph.
|
||||
graph->set_osr(this);
|
||||
|
||||
HBasicBlock* non_osr_entry = graph->CreateBasicBlock();
|
||||
osr_entry_ = graph->CreateBasicBlock();
|
||||
HValue* true_value = graph->GetConstantTrue();
|
||||
HBranch* test = new(zone) HBranch(true_value, non_osr_entry, osr_entry_);
|
||||
builder_->current_block()->Finish(test);
|
||||
|
||||
HBasicBlock* loop_predecessor = graph->CreateBasicBlock();
|
||||
non_osr_entry->Goto(loop_predecessor);
|
||||
|
||||
builder_->set_current_block(osr_entry_);
|
||||
osr_entry_->set_osr_entry();
|
||||
BailoutId osr_entry_id = statement->OsrEntryId();
|
||||
|
||||
HEnvironment *environment = builder_->environment();
|
||||
int first_expression_index = environment->first_expression_index();
|
||||
int length = environment->length();
|
||||
osr_values_ = new(zone) ZoneList<HUnknownOSRValue*>(length, zone);
|
||||
|
||||
for (int i = 0; i < first_expression_index; ++i) {
|
||||
HUnknownOSRValue* osr_value = builder_->Add<HUnknownOSRValue>();
|
||||
environment->Bind(i, osr_value);
|
||||
osr_values_->Add(osr_value, zone);
|
||||
}
|
||||
|
||||
if (first_expression_index != length) {
|
||||
environment->Drop(length - first_expression_index);
|
||||
for (int i = first_expression_index; i < length; ++i) {
|
||||
HUnknownOSRValue* osr_value = builder_->Add<HUnknownOSRValue>();
|
||||
environment->Push(osr_value);
|
||||
osr_values_->Add(osr_value, zone);
|
||||
}
|
||||
}
|
||||
|
||||
builder_->AddSimulate(osr_entry_id);
|
||||
builder_->Add<HOsrEntry>(osr_entry_id);
|
||||
HContext* context = builder_->Add<HContext>();
|
||||
environment->BindContext(context);
|
||||
builder_->current_block()->Goto(loop_predecessor);
|
||||
loop_predecessor->SetJoinId(statement->EntryId());
|
||||
builder_->set_current_block(loop_predecessor);
|
||||
|
||||
// Create the final loop entry
|
||||
osr_loop_entry_ = BuildLoopEntry();
|
||||
return osr_loop_entry_;
|
||||
}
|
||||
|
||||
|
||||
void HOsrBuilder::FinishGraph() {
|
||||
// do nothing for now.
|
||||
}
|
||||
|
||||
|
||||
void HOsrBuilder::FinishOsrValues() {
|
||||
const ZoneList<HPhi*>* phis = osr_loop_entry_->phis();
|
||||
for (int j = 0; j < phis->length(); j++) {
|
||||
HPhi* phi = phis->at(j);
|
||||
osr_values_->at(phi->merged_index())->set_incoming_value(phi);
|
||||
}
|
||||
}
|
||||
|
||||
} } // namespace v8::internal
|
70
src/hydrogen-osr.h
Normal file
70
src/hydrogen-osr.h
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef V8_HYDROGEN_OSR_H_
|
||||
#define V8_HYDROGEN_OSR_H_
|
||||
|
||||
#include "hydrogen.h"
|
||||
#include "ast.h"
|
||||
#include "zone.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// Responsible for building graph parts related to OSR and otherwise
|
||||
// setting up the graph to do an OSR compile.
|
||||
class HOsrBuilder : public ZoneObject {
|
||||
public:
|
||||
explicit HOsrBuilder(HOptimizedGraphBuilder* builder)
|
||||
: builder_(builder),
|
||||
osr_entry_(NULL),
|
||||
osr_loop_entry_(NULL),
|
||||
osr_values_(NULL) { }
|
||||
// Creates the loop entry block for the given statement, setting up OSR
|
||||
// entries as necessary, and sets the current block to the new block.
|
||||
HBasicBlock* BuildPossibleOsrLoopEntry(IterationStatement* statement);
|
||||
|
||||
// Process the hydrogen graph after it has been completed, performing
|
||||
// any OSR-specific cleanups or changes.
|
||||
void FinishGraph();
|
||||
|
||||
// Process the OSR values and phis after initial graph optimization.
|
||||
void FinishOsrValues();
|
||||
|
||||
private:
|
||||
HBasicBlock* BuildLoopEntry();
|
||||
bool HasOsrEntryAt(IterationStatement* statement);
|
||||
|
||||
HOptimizedGraphBuilder* builder_;
|
||||
HBasicBlock* osr_entry_;
|
||||
HBasicBlock* osr_loop_entry_;
|
||||
ZoneList<HUnknownOSRValue*>* osr_values_;
|
||||
};
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_HYDROGEN_OSR_H_
|
@ -37,6 +37,7 @@
|
||||
#include "hydrogen-escape-analysis.h"
|
||||
#include "hydrogen-infer-representation.h"
|
||||
#include "hydrogen-gvn.h"
|
||||
#include "hydrogen-osr.h"
|
||||
#include "hydrogen-uint32-analysis.h"
|
||||
#include "lithium-allocator.h"
|
||||
#include "parser.h"
|
||||
@ -1915,7 +1916,8 @@ HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info)
|
||||
break_scope_(NULL),
|
||||
inlined_count_(0),
|
||||
globals_(10, info->zone()),
|
||||
inline_bailout_(false) {
|
||||
inline_bailout_(false),
|
||||
osr_(new(info->zone()) HOsrBuilder(this)) {
|
||||
// This is not initialized in the initializer list because the
|
||||
// constructor for the initial state relies on function_state_ == NULL
|
||||
// to know it's the initial state.
|
||||
@ -1983,6 +1985,7 @@ HGraph::HGraph(CompilationInfo* info)
|
||||
values_(16, info->zone()),
|
||||
phi_list_(NULL),
|
||||
uint32_instructions_(NULL),
|
||||
osr_(NULL),
|
||||
info_(info),
|
||||
zone_(info->zone()),
|
||||
is_recursive_(false),
|
||||
@ -3532,6 +3535,9 @@ bool HOptimizedGraphBuilder::BuildGraph() {
|
||||
!type_info->matches_inlined_type_change_checksum(composite_checksum));
|
||||
type_info->set_inlined_type_change_checksum(composite_checksum);
|
||||
|
||||
// Perform any necessary OSR-specific cleanups or changes to the graph.
|
||||
osr_->FinishGraph();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3575,13 +3581,7 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
|
||||
}
|
||||
CollectPhis();
|
||||
|
||||
if (has_osr_loop_entry()) {
|
||||
const ZoneList<HPhi*>* phis = osr_loop_entry()->phis();
|
||||
for (int j = 0; j < phis->length(); j++) {
|
||||
HPhi* phi = phis->at(j);
|
||||
osr_values()->at(phi->merged_index())->set_incoming_value(phi);
|
||||
}
|
||||
}
|
||||
if (has_osr()) osr()->FinishOsrValues();
|
||||
|
||||
Run<HInferRepresentationPhase>();
|
||||
|
||||
@ -4689,59 +4689,6 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
}
|
||||
|
||||
|
||||
bool HOptimizedGraphBuilder::HasOsrEntryAt(IterationStatement* statement) {
|
||||
return statement->OsrEntryId() == current_info()->osr_ast_id();
|
||||
}
|
||||
|
||||
|
||||
bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
|
||||
if (!HasOsrEntryAt(statement)) return false;
|
||||
|
||||
HBasicBlock* non_osr_entry = graph()->CreateBasicBlock();
|
||||
HBasicBlock* osr_entry = graph()->CreateBasicBlock();
|
||||
HValue* true_value = graph()->GetConstantTrue();
|
||||
HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry);
|
||||
current_block()->Finish(test);
|
||||
|
||||
HBasicBlock* loop_predecessor = graph()->CreateBasicBlock();
|
||||
non_osr_entry->Goto(loop_predecessor);
|
||||
|
||||
set_current_block(osr_entry);
|
||||
osr_entry->set_osr_entry();
|
||||
BailoutId osr_entry_id = statement->OsrEntryId();
|
||||
int first_expression_index = environment()->first_expression_index();
|
||||
int length = environment()->length();
|
||||
ZoneList<HUnknownOSRValue*>* osr_values =
|
||||
new(zone()) ZoneList<HUnknownOSRValue*>(length, zone());
|
||||
|
||||
for (int i = 0; i < first_expression_index; ++i) {
|
||||
HUnknownOSRValue* osr_value = Add<HUnknownOSRValue>();
|
||||
environment()->Bind(i, osr_value);
|
||||
osr_values->Add(osr_value, zone());
|
||||
}
|
||||
|
||||
if (first_expression_index != length) {
|
||||
environment()->Drop(length - first_expression_index);
|
||||
for (int i = first_expression_index; i < length; ++i) {
|
||||
HUnknownOSRValue* osr_value = Add<HUnknownOSRValue>();
|
||||
environment()->Push(osr_value);
|
||||
osr_values->Add(osr_value, zone());
|
||||
}
|
||||
}
|
||||
|
||||
graph()->set_osr_values(osr_values);
|
||||
|
||||
AddSimulate(osr_entry_id);
|
||||
Add<HOsrEntry>(osr_entry_id);
|
||||
HContext* context = Add<HContext>();
|
||||
environment()->BindContext(context);
|
||||
current_block()->Goto(loop_predecessor);
|
||||
loop_predecessor->SetJoinId(statement->EntryId());
|
||||
set_current_block(loop_predecessor);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
|
||||
HBasicBlock* loop_entry,
|
||||
BreakAndContinueInfo* break_info) {
|
||||
@ -4761,11 +4708,7 @@ void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
||||
ASSERT(current_block() != NULL);
|
||||
ASSERT(current_block()->HasPredecessor());
|
||||
ASSERT(current_block() != NULL);
|
||||
bool osr_entry = PreProcessOsrEntry(stmt);
|
||||
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
|
||||
current_block()->Goto(loop_entry);
|
||||
set_current_block(loop_entry);
|
||||
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
|
||||
HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
|
||||
|
||||
BreakAndContinueInfo break_info(stmt);
|
||||
CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
|
||||
@ -4804,12 +4747,7 @@ void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
|
||||
ASSERT(current_block() != NULL);
|
||||
ASSERT(current_block()->HasPredecessor());
|
||||
ASSERT(current_block() != NULL);
|
||||
bool osr_entry = PreProcessOsrEntry(stmt);
|
||||
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
|
||||
current_block()->Goto(loop_entry);
|
||||
set_current_block(loop_entry);
|
||||
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
|
||||
|
||||
HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
|
||||
|
||||
// If the condition is constant true, do not generate a branch.
|
||||
HBasicBlock* loop_successor = NULL;
|
||||
@ -4851,11 +4789,7 @@ void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) {
|
||||
CHECK_ALIVE(Visit(stmt->init()));
|
||||
}
|
||||
ASSERT(current_block() != NULL);
|
||||
bool osr_entry = PreProcessOsrEntry(stmt);
|
||||
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
|
||||
current_block()->Goto(loop_entry);
|
||||
set_current_block(loop_entry);
|
||||
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
|
||||
HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
|
||||
|
||||
HBasicBlock* loop_successor = NULL;
|
||||
if (stmt->cond() != NULL) {
|
||||
@ -4939,11 +4873,7 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
|
||||
HForInCacheArray::cast(array)->set_index_cache(
|
||||
HForInCacheArray::cast(index_cache));
|
||||
|
||||
bool osr_entry = PreProcessOsrEntry(stmt);
|
||||
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
|
||||
current_block()->Goto(loop_entry);
|
||||
set_current_block(loop_entry);
|
||||
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
|
||||
HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
|
||||
|
||||
HValue* index = environment()->ExpressionStackAt(0);
|
||||
HValue* limit = environment()->ExpressionStackAt(1);
|
||||
|
@ -46,6 +46,7 @@ class FunctionState;
|
||||
class HEnvironment;
|
||||
class HGraph;
|
||||
class HLoopInformation;
|
||||
class HOsrBuilder;
|
||||
class HTracer;
|
||||
class LAllocator;
|
||||
class LChunk;
|
||||
@ -358,24 +359,16 @@ class HGraph: public ZoneObject {
|
||||
void Verify(bool do_full_verify) const;
|
||||
#endif
|
||||
|
||||
bool has_osr_loop_entry() {
|
||||
return osr_loop_entry_.is_set();
|
||||
bool has_osr() {
|
||||
return osr_ != NULL;
|
||||
}
|
||||
|
||||
HBasicBlock* osr_loop_entry() {
|
||||
return osr_loop_entry_.get();
|
||||
void set_osr(HOsrBuilder* osr) {
|
||||
osr_ = osr;
|
||||
}
|
||||
|
||||
void set_osr_loop_entry(HBasicBlock* entry) {
|
||||
osr_loop_entry_.set(entry);
|
||||
}
|
||||
|
||||
ZoneList<HUnknownOSRValue*>* osr_values() {
|
||||
return osr_values_.get();
|
||||
}
|
||||
|
||||
void set_osr_values(ZoneList<HUnknownOSRValue*>* values) {
|
||||
osr_values_.set(values);
|
||||
HOsrBuilder* osr() {
|
||||
return osr_;
|
||||
}
|
||||
|
||||
int update_type_change_checksum(int delta) {
|
||||
@ -495,8 +488,7 @@ class HGraph: public ZoneObject {
|
||||
SetOncePointer<HConstant> constant_invalid_context_;
|
||||
SetOncePointer<HArgumentsObject> arguments_object_;
|
||||
|
||||
SetOncePointer<HBasicBlock> osr_loop_entry_;
|
||||
SetOncePointer<ZoneList<HUnknownOSRValue*> > osr_values_;
|
||||
HOsrBuilder* osr_;
|
||||
|
||||
CompilationInfo* info_;
|
||||
Zone* zone_;
|
||||
@ -1438,7 +1430,6 @@ class HGraphBuilder {
|
||||
int no_side_effects_scope_count_;
|
||||
};
|
||||
|
||||
|
||||
class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
|
||||
public:
|
||||
// A class encapsulating (lazily-allocated) break and continue blocks for
|
||||
@ -1596,8 +1587,6 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
|
||||
void VisitArithmeticExpression(BinaryOperation* expr);
|
||||
|
||||
bool PreProcessOsrEntry(IterationStatement* statement);
|
||||
// True iff. we are compiling for OSR and the statement is the entry.
|
||||
bool HasOsrEntryAt(IterationStatement* statement);
|
||||
void VisitLoopBody(IterationStatement* stmt,
|
||||
HBasicBlock* loop_entry,
|
||||
BreakAndContinueInfo* break_info);
|
||||
@ -1959,9 +1948,12 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
|
||||
|
||||
bool inline_bailout_;
|
||||
|
||||
HOsrBuilder* osr_;
|
||||
|
||||
friend class FunctionState; // Pushes and pops the state stack.
|
||||
friend class AstContext; // Pushes and pops the AST context stack.
|
||||
friend class KeyedLoadFastElementStub;
|
||||
friend class HOsrBuilder;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(HOptimizedGraphBuilder);
|
||||
};
|
||||
|
@ -349,6 +349,8 @@
|
||||
'../../src/hydrogen-infer-representation.h',
|
||||
'../../src/hydrogen-uint32-analysis.cc',
|
||||
'../../src/hydrogen-uint32-analysis.h',
|
||||
'../../src/hydrogen-osr.cc',
|
||||
'../../src/hydrogen-osr.h',
|
||||
'../../src/ic-inl.h',
|
||||
'../../src/ic.cc',
|
||||
'../../src/ic.h',
|
||||
|
Loading…
Reference in New Issue
Block a user