Commit 493a7d64 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[TurboFan] Delete AstGraphBuilder.

Deletes AstGraphBuilder and associated classes now that it is
unreachable. The following classes are also removed:
 - ControlBuilders
 - JSFrameSpecialization
 - AstLoopAssignmentAnalysis

Also removes flags from compilation-info which are no longer used, and removes
the no-deoptimization paths from TypedOptimization, JsTypedLowering,
JSIntrinsicLowering and JSBuiltinLowering.

BUG=v8:6409

Change-Id: I63986e8e3497bf63c4a27ea8ae827b8a633d4a26
Reviewed-on: https://chromium-review.googlesource.com/583652
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47284}
parent dadbde03
......@@ -1289,10 +1289,6 @@ v8_source_set("v8_base") {
"src/compiler/access-info.h",
"src/compiler/all-nodes.cc",
"src/compiler/all-nodes.h",
"src/compiler/ast-graph-builder.cc",
"src/compiler/ast-graph-builder.h",
"src/compiler/ast-loop-assignment-analyzer.cc",
"src/compiler/ast-loop-assignment-analyzer.h",
"src/compiler/basic-block-instrumentor.cc",
"src/compiler/basic-block-instrumentor.h",
"src/compiler/branch-elimination.cc",
......@@ -1319,8 +1315,6 @@ v8_source_set("v8_base") {
"src/compiler/common-operator.h",
"src/compiler/compiler-source-position-table.cc",
"src/compiler/compiler-source-position-table.h",
"src/compiler/control-builders.cc",
"src/compiler/control-builders.h",
"src/compiler/control-equivalence.cc",
"src/compiler/control-equivalence.h",
"src/compiler/control-flow-optimizer.cc",
......@@ -1370,8 +1364,6 @@ v8_source_set("v8_base") {
"src/compiler/js-context-specialization.h",
"src/compiler/js-create-lowering.cc",
"src/compiler/js-create-lowering.h",
"src/compiler/js-frame-specialization.cc",
"src/compiler/js-frame-specialization.h",
"src/compiler/js-generic-lowering.cc",
"src/compiler/js-generic-lowering.h",
"src/compiler/js-graph.cc",
......
......@@ -41,18 +41,14 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
kIsNative = 1 << 2,
kSerializing = 1 << 3,
kBlockCoverageEnabled = 1 << 4,
kRequiresFrame = 1 << 5,
kAccessorInliningEnabled = 1 << 6,
kFunctionContextSpecializing = 1 << 7,
kFrameSpecializing = 1 << 8,
kInliningEnabled = 1 << 9,
kDisableFutureOptimization = 1 << 10,
kSplittingEnabled = 1 << 11,
kDeoptimizationEnabled = 1 << 12,
kSourcePositionsEnabled = 1 << 13,
kBailoutOnUninitialized = 1 << 14,
kOptimizeFromBytecode = 1 << 15,
kLoopPeelingEnabled = 1 << 16,
kAccessorInliningEnabled = 1 << 5,
kFunctionContextSpecializing = 1 << 6,
kInliningEnabled = 1 << 7,
kDisableFutureOptimization = 1 << 8,
kSplittingEnabled = 1 << 9,
kSourcePositionsEnabled = 1 << 10,
kBailoutOnUninitialized = 1 << 11,
kLoopPeelingEnabled = 1 << 12,
};
// Construct a compilation info for unoptimized compilation.
......@@ -133,9 +129,6 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
// Flags used by optimized compilation.
void MarkAsRequiresFrame() { SetFlag(kRequiresFrame); }
bool requires_frame() const { return GetFlag(kRequiresFrame); }
void MarkAsFunctionContextSpecializing() {
SetFlag(kFunctionContextSpecializing);
}
......@@ -143,14 +136,6 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
return GetFlag(kFunctionContextSpecializing);
}
void MarkAsFrameSpecializing() { SetFlag(kFrameSpecializing); }
bool is_frame_specializing() const { return GetFlag(kFrameSpecializing); }
void MarkAsDeoptimizationEnabled() { SetFlag(kDeoptimizationEnabled); }
bool is_deoptimization_enabled() const {
return GetFlag(kDeoptimizationEnabled);
}
void MarkAsAccessorInliningEnabled() { SetFlag(kAccessorInliningEnabled); }
bool is_accessor_inlining_enabled() const {
return GetFlag(kAccessorInliningEnabled);
......@@ -172,11 +157,6 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
return GetFlag(kBailoutOnUninitialized);
}
void MarkAsOptimizeFromBytecode() { SetFlag(kOptimizeFromBytecode); }
bool is_optimizing_from_bytecode() const {
return GetFlag(kOptimizeFromBytecode);
}
void MarkAsLoopPeelingEnabled() { SetFlag(kLoopPeelingEnabled); }
bool is_loop_peeling_enabled() const { return GetFlag(kLoopPeelingEnabled); }
......
......@@ -563,8 +563,6 @@ void InsertCodeIntoOptimizedCodeCache(CompilationInfo* compilation_info) {
ClearOptimizedCodeCache(compilation_info);
return;
}
// Frame specialization implies function context specialization.
DCHECK(!compilation_info->is_frame_specializing());
// Cache optimized context-specific code.
Handle<JSFunction> function = compilation_info->closure();
......@@ -715,9 +713,6 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode");
// TODO(rmcilroy): Remove OptimizeFromBytecode flag.
compilation_info->MarkAsOptimizeFromBytecode();
// In case of concurrent recompilation, all handles below this point will be
// allocated in a deferred handle scope that is detached and handed off to
// the background thread when we return.
......
This diff is collapsed.
This diff is collapsed.
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/ast-loop-assignment-analyzer.h"
#include "src/ast/scopes.h"
#include "src/compilation-info.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
namespace compiler {
typedef class AstLoopAssignmentAnalyzer ALAA; // for code shortitude.
ALAA::AstLoopAssignmentAnalyzer(Zone* zone, CompilationInfo* info)
: info_(info), zone_(zone), loop_stack_(zone) {
InitializeAstVisitor(info->isolate());
}
LoopAssignmentAnalysis* ALAA::Analyze() {
LoopAssignmentAnalysis* a = new (zone_) LoopAssignmentAnalysis(zone_);
result_ = a;
VisitStatements(info()->literal()->body());
result_ = nullptr;
return a;
}
void ALAA::Enter(IterationStatement* loop) {
int num_variables = 1 + info()->scope()->num_parameters() +
info()->scope()->num_stack_slots();
BitVector* bits = new (zone_) BitVector(num_variables, zone_);
if (info()->is_osr() && info()->osr_ast_id() == loop->OsrEntryId())
bits->AddAll();
loop_stack_.push_back(bits);
}
void ALAA::Exit(IterationStatement* loop) {
DCHECK(loop_stack_.size() > 0);
BitVector* bits = loop_stack_.back();
loop_stack_.pop_back();
if (!loop_stack_.empty()) {
loop_stack_.back()->Union(*bits);
}
result_->list_.push_back(
std::pair<IterationStatement*, BitVector*>(loop, bits));
}
// ---------------------------------------------------------------------------
// -- Leaf nodes -------------------------------------------------------------
// ---------------------------------------------------------------------------
void ALAA::VisitVariableDeclaration(VariableDeclaration* leaf) {}
void ALAA::VisitFunctionDeclaration(FunctionDeclaration* leaf) {}
void ALAA::VisitEmptyStatement(EmptyStatement* leaf) {}
void ALAA::VisitContinueStatement(ContinueStatement* leaf) {}
void ALAA::VisitBreakStatement(BreakStatement* leaf) {}
void ALAA::VisitDebuggerStatement(DebuggerStatement* leaf) {}
void ALAA::VisitFunctionLiteral(FunctionLiteral* leaf) {}
void ALAA::VisitNativeFunctionLiteral(NativeFunctionLiteral* leaf) {}
void ALAA::VisitVariableProxy(VariableProxy* leaf) {}
void ALAA::VisitLiteral(Literal* leaf) {}
void ALAA::VisitRegExpLiteral(RegExpLiteral* leaf) {}
void ALAA::VisitThisFunction(ThisFunction* leaf) {}
void ALAA::VisitSuperPropertyReference(SuperPropertyReference* leaf) {}
void ALAA::VisitSuperCallReference(SuperCallReference* leaf) {}
// ---------------------------------------------------------------------------
// -- Pass-through nodes------------------------------------------------------
// ---------------------------------------------------------------------------
void ALAA::VisitBlock(Block* stmt) { VisitStatements(stmt->statements()); }
void ALAA::VisitDoExpression(DoExpression* expr) {
Visit(expr->block());
Visit(expr->result());
}
void ALAA::VisitExpressionStatement(ExpressionStatement* stmt) {
Visit(stmt->expression());
}
void ALAA::VisitIfStatement(IfStatement* stmt) {
Visit(stmt->condition());
Visit(stmt->then_statement());
Visit(stmt->else_statement());
}
void ALAA::VisitReturnStatement(ReturnStatement* stmt) {
Visit(stmt->expression());
}
void ALAA::VisitWithStatement(WithStatement* stmt) {
Visit(stmt->expression());
Visit(stmt->statement());
}
void ALAA::VisitSwitchStatement(SwitchStatement* stmt) {
Visit(stmt->tag());
ZoneList<CaseClause*>* clauses = stmt->cases();
for (int i = 0; i < clauses->length(); i++) {
Visit(clauses->at(i));
}
}
void ALAA::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
Visit(stmt->try_block());
Visit(stmt->finally_block());
}
void ALAA::VisitClassLiteral(ClassLiteral* e) {
VisitIfNotNull(e->extends());
VisitIfNotNull(e->constructor());
ZoneList<ClassLiteralProperty*>* properties = e->properties();
for (int i = 0; i < properties->length(); i++) {
Visit(properties->at(i)->key());
Visit(properties->at(i)->value());
}
}
void ALAA::VisitConditional(Conditional* e) {
Visit(e->condition());
Visit(e->then_expression());
Visit(e->else_expression());
}
void ALAA::VisitObjectLiteral(ObjectLiteral* e) {
ZoneList<ObjectLiteralProperty*>* properties = e->properties();
for (int i = 0; i < properties->length(); i++) {
Visit(properties->at(i)->key());
Visit(properties->at(i)->value());
}
}
void ALAA::VisitArrayLiteral(ArrayLiteral* e) { VisitExpressions(e->values()); }
void ALAA::VisitYield(Yield* e) { Visit(e->expression()); }
void ALAA::VisitYieldStar(YieldStar* e) { Visit(e->expression()); }
void ALAA::VisitAwait(Await* e) { Visit(e->expression()); }
void ALAA::VisitThrow(Throw* stmt) { Visit(stmt->exception()); }
void ALAA::VisitProperty(Property* e) {
Visit(e->obj());
Visit(e->key());
}
void ALAA::VisitCall(Call* e) {
Visit(e->expression());
VisitExpressions(e->arguments());
}
void ALAA::VisitCallNew(CallNew* e) {
Visit(e->expression());
VisitExpressions(e->arguments());
}
void ALAA::VisitCallRuntime(CallRuntime* e) {
VisitExpressions(e->arguments());
}
void ALAA::VisitUnaryOperation(UnaryOperation* e) { Visit(e->expression()); }
void ALAA::VisitBinaryOperation(BinaryOperation* e) {
Visit(e->left());
Visit(e->right());
}
void ALAA::VisitCompareOperation(CompareOperation* e) {
Visit(e->left());
Visit(e->right());
}
void ALAA::VisitSpread(Spread* e) { UNREACHABLE(); }
void ALAA::VisitEmptyParentheses(EmptyParentheses* e) { UNREACHABLE(); }
void ALAA::VisitGetIterator(GetIterator* e) { UNREACHABLE(); }
void ALAA::VisitImportCallExpression(ImportCallExpression* e) { UNREACHABLE(); }
void ALAA::VisitCaseClause(CaseClause* cc) {
if (!cc->is_default()) Visit(cc->label());
VisitStatements(cc->statements());
}
void ALAA::VisitSloppyBlockFunctionStatement(
SloppyBlockFunctionStatement* stmt) {
Visit(stmt->statement());
}
// ---------------------------------------------------------------------------
// -- Interesting nodes-------------------------------------------------------
// ---------------------------------------------------------------------------
void ALAA::VisitTryCatchStatement(TryCatchStatement* stmt) {
Visit(stmt->try_block());
Visit(stmt->catch_block());
AnalyzeAssignment(stmt->scope()->catch_variable());
}
void ALAA::VisitDoWhileStatement(DoWhileStatement* loop) {
Enter(loop);
Visit(loop->body());
Visit(loop->cond());
Exit(loop);
}
void ALAA::VisitWhileStatement(WhileStatement* loop) {
Enter(loop);
Visit(loop->cond());
Visit(loop->body());
Exit(loop);
}
void ALAA::VisitForStatement(ForStatement* loop) {
VisitIfNotNull(loop->init());
Enter(loop);
VisitIfNotNull(loop->cond());
Visit(loop->body());
VisitIfNotNull(loop->next());
Exit(loop);
}
void ALAA::VisitForInStatement(ForInStatement* loop) {
Expression* l = loop->each();
Enter(loop);
Visit(l);
Visit(loop->subject());
Visit(loop->body());
if (l->IsVariableProxy()) AnalyzeAssignment(l->AsVariableProxy()->var());
Exit(loop);
}
void ALAA::VisitForOfStatement(ForOfStatement* loop) {
Visit(loop->assign_iterator());
Enter(loop);
Visit(loop->next_result());
Visit(loop->result_done());
Visit(loop->assign_each());
Visit(loop->body());
Exit(loop);
}
void ALAA::VisitAssignment(Assignment* stmt) {
Expression* l = stmt->target();
Visit(l);
Visit(stmt->value());
if (l->IsVariableProxy()) AnalyzeAssignment(l->AsVariableProxy()->var());
}
void ALAA::VisitCountOperation(CountOperation* e) {
Expression* l = e->expression();
Visit(l);
if (l->IsVariableProxy()) AnalyzeAssignment(l->AsVariableProxy()->var());
}
void ALAA::VisitRewritableExpression(RewritableExpression* expr) {
Visit(expr->expression());
}
void ALAA::AnalyzeAssignment(Variable* var) {
if (!loop_stack_.empty() && var->IsStackAllocated()) {
loop_stack_.back()->Add(GetVariableIndex(info()->scope(), var));
}
}
int ALAA::GetVariableIndex(DeclarationScope* scope, Variable* var) {
CHECK(var->IsStackAllocated());
if (var->is_this()) return 0;
if (var->IsParameter()) return 1 + var->index();
return 1 + scope->num_parameters() + var->index();
}
int LoopAssignmentAnalysis::GetAssignmentCountForTesting(
DeclarationScope* scope, Variable* var) {
int count = 0;
int var_index = AstLoopAssignmentAnalyzer::GetVariableIndex(scope, var);
for (size_t i = 0; i < list_.size(); i++) {
if (list_[i].second->Contains(var_index)) count++;
}
return count;
}
} // namespace compiler
} // namespace internal
} // namespace v8
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_AST_LOOP_ASSIGNMENT_ANALYZER_H_
#define V8_COMPILER_AST_LOOP_ASSIGNMENT_ANALYZER_H_
#include "src/ast/ast.h"
#include "src/bit-vector.h"
#include "src/zone/zone-containers.h"
namespace v8 {
namespace internal {
class CompilationInfo;
class Scope;
class Variable;
namespace compiler {
// The result of analyzing loop assignments.
class LoopAssignmentAnalysis : public ZoneObject {
public:
BitVector* GetVariablesAssignedInLoop(IterationStatement* loop) {
for (size_t i = 0; i < list_.size(); i++) {
// TODO(turbofan): hashmap or binary search for loop assignments.
if (list_[i].first == loop) return list_[i].second;
}
UNREACHABLE(); // should never ask for loops that aren't here!
return nullptr;
}
int GetAssignmentCountForTesting(DeclarationScope* scope, Variable* var);
private:
friend class AstLoopAssignmentAnalyzer;
explicit LoopAssignmentAnalysis(Zone* zone) : list_(zone) {}
ZoneVector<std::pair<IterationStatement*, BitVector*>> list_;
};
// The class that performs loop assignment analysis by walking the AST.
class AstLoopAssignmentAnalyzer final
: public AstVisitor<AstLoopAssignmentAnalyzer> {
public:
AstLoopAssignmentAnalyzer(Zone* zone, CompilationInfo* info);
LoopAssignmentAnalysis* Analyze();
#define DECLARE_VISIT(type) void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
static int GetVariableIndex(DeclarationScope* scope, Variable* var);
private:
CompilationInfo* info_;
Zone* zone_;
ZoneDeque<BitVector*> loop_stack_;
LoopAssignmentAnalysis* result_;
CompilationInfo* info() { return info_; }
void Enter(IterationStatement* loop);
void Exit(IterationStatement* loop);
void VisitIfNotNull(AstNode* node) {
if (node != nullptr) Visit(node);
}
void AnalyzeAssignment(Variable* var);
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
DISALLOW_COPY_AND_ASSIGN(AstLoopAssignmentAnalyzer);
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_AST_LOOP_ASSIGNMENT_ANALYZER_H_
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/control-builders.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
namespace compiler {
void IfBuilder::If(Node* condition, BranchHint hint) {
builder_->NewBranch(condition, hint);
else_environment_ = environment()->CopyForConditional();
}
void IfBuilder::Then() { builder_->NewIfTrue(); }
void IfBuilder::Else() {
builder_->NewMerge();
then_environment_ = environment();
set_environment(else_environment_);
builder_->NewIfFalse();
}
void IfBuilder::End() {
then_environment_->Merge(environment());
set_environment(then_environment_);
}
void LoopBuilder::BeginLoop(BitVector* assigned, bool is_osr) {
loop_environment_ = environment()->CopyForLoop(assigned, is_osr);
continue_environment_ = environment()->CopyAsUnreachable();
break_environment_ = environment()->CopyAsUnreachable();
assigned_ = assigned;
}
void LoopBuilder::Continue() {
continue_environment_->Merge(environment());
environment()->MarkAsUnreachable();
}
void LoopBuilder::Break() {
break_environment_->Merge(environment());
environment()->MarkAsUnreachable();
}
void LoopBuilder::EndBody() {
continue_environment_->Merge(environment());
set_environment(continue_environment_);
}
void LoopBuilder::EndLoop() {
loop_environment_->Merge(environment());
set_environment(break_environment_);
ExitLoop();
}
void LoopBuilder::BreakUnless(Node* condition) {
IfBuilder control_if(builder_);
control_if.If(condition);
control_if.Then();
control_if.Else();
Break();
control_if.End();
}
void LoopBuilder::BreakWhen(Node* condition) {
IfBuilder control_if(builder_);
control_if.If(condition);
control_if.Then();
Break();
control_if.Else();
control_if.End();
}
void LoopBuilder::ExitLoop(Node** extra_value_to_rename) {
if (extra_value_to_rename) {
environment()->Push(*extra_value_to_rename);
}
environment()->PrepareForLoopExit(loop_environment_->GetControlDependency(),
assigned_);
if (extra_value_to_rename) {
*extra_value_to_rename = environment()->Pop();
}
}
void SwitchBuilder::BeginSwitch() {
body_environment_ = environment()->CopyAsUnreachable();
label_environment_ = environment()->CopyAsUnreachable();
break_environment_ = environment()->CopyAsUnreachable();
}
void SwitchBuilder::BeginLabel(int index, Node* condition) {
builder_->NewBranch(condition);
label_environment_ = environment()->CopyForConditional();
builder_->NewIfTrue();
body_environments_[index] = environment();
}
void SwitchBuilder::EndLabel() {
set_environment(label_environment_);
builder_->NewIfFalse();
}
void SwitchBuilder::DefaultAt(int index) {
label_environment_ = environment()->CopyAsUnreachable();
body_environments_[index] = environment();
}
void SwitchBuilder::BeginCase(int index) {
set_environment(body_environments_[index]);
environment()->Merge(body_environment_);
}
void SwitchBuilder::Break() {
break_environment_->Merge(environment());
environment()->MarkAsUnreachable();
}
void SwitchBuilder::EndCase() { body_environment_ = environment(); }
void SwitchBuilder::EndSwitch() {
break_environment_->Merge(label_environment_);
break_environment_->Merge(environment());
set_environment(break_environment_);
}
void BlockBuilder::BeginBlock() {
break_environment_ = environment()->CopyAsUnreachable();
}
void BlockBuilder::Break() {
break_environment_->Merge(environment());
environment()->MarkAsUnreachable();
}
void BlockBuilder::BreakWhen(Node* condition, BranchHint hint) {
IfBuilder control_if(builder_);
control_if.If(condition, hint);
control_if.Then();
Break();
control_if.Else();
control_if.End();
}
void BlockBuilder::BreakUnless(Node* condition, BranchHint hint) {
IfBuilder control_if(builder_);
control_if.If(condition, hint);
control_if.Then();
control_if.Else();
Break();
control_if.End();
}
void BlockBuilder::EndBlock() {
break_environment_->Merge(environment());
set_environment(break_environment_);
}
} // namespace compiler
} // namespace internal
} // namespace v8
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_CONTROL_BUILDERS_H_
#define V8_COMPILER_CONTROL_BUILDERS_H_
#include "src/compiler/ast-graph-builder.h"
#include "src/compiler/node.h"
namespace v8 {
namespace internal {
namespace compiler {
// Base class for all control builders. Also provides a common interface for
// control builders to handle 'break' statements when they are used to model
// breakable statements.
class ControlBuilder {
public:
explicit ControlBuilder(AstGraphBuilder* builder) : builder_(builder) {}
virtual ~ControlBuilder() {}
// Interface for break.
virtual void Break() { UNREACHABLE(); }
protected:
typedef AstGraphBuilder Builder;
typedef AstGraphBuilder::Environment Environment;
Zone* zone() const { return builder_->local_zone(); }
Environment* environment() { return builder_->environment(); }
void set_environment(Environment* env) { builder_->set_environment(env); }
Node* the_hole() const { return builder_->jsgraph()->TheHoleConstant(); }
Builder* builder_;
};
// Tracks control flow for a conditional statement.
class IfBuilder final : public ControlBuilder {
public:
explicit IfBuilder(AstGraphBuilder* builder)
: ControlBuilder(builder),
then_environment_(nullptr),
else_environment_(nullptr) {}
// Primitive control commands.
void If(Node* condition, BranchHint hint = BranchHint::kNone);
void Then();
void Else();
void End();
private:
Environment* then_environment_; // Environment after the 'then' body.
Environment* else_environment_; // Environment for the 'else' body.
};
// Tracks control flow for an iteration statement.
class LoopBuilder final : public ControlBuilder {
public:
explicit LoopBuilder(AstGraphBuilder* builder)
: ControlBuilder(builder),
loop_environment_(nullptr),
continue_environment_(nullptr),
break_environment_(nullptr),
assigned_(nullptr) {}
// Primitive control commands.
void BeginLoop(BitVector* assigned, bool is_osr = false);
void Continue();
void EndBody();
void EndLoop();
// Primitive support for break.
void Break() final;
// Loop exit support. Used to introduce explicit loop exit control
// node and variable markers.
void ExitLoop(Node** extra_value_to_rename = nullptr);
// Compound control commands for conditional break.
void BreakUnless(Node* condition);
void BreakWhen(Node* condition);
private:
Environment* loop_environment_; // Environment of the loop header.
Environment* continue_environment_; // Environment after the loop body.
Environment* break_environment_; // Environment after the loop exits.
BitVector* assigned_; // Assigned values in the environment.
};
// Tracks control flow for a switch statement.
class SwitchBuilder final : public ControlBuilder {
public:
explicit SwitchBuilder(AstGraphBuilder* builder, int case_count)
: ControlBuilder(builder),
body_environment_(nullptr),
label_environment_(nullptr),
break_environment_(nullptr),
body_environments_(case_count, zone()) {}
// Primitive control commands.
void BeginSwitch();
void BeginLabel(int index, Node* condition);
void EndLabel();
void DefaultAt(int index);
void BeginCase(int index);
void EndCase();
void EndSwitch();
// Primitive support for break.
void Break() final;
// The number of cases within a switch is statically known.
size_t case_count() const { return body_environments_.size(); }
private:
Environment* body_environment_; // Environment after last case body.
Environment* label_environment_; // Environment for next label condition.
Environment* break_environment_; // Environment after the switch exits.
ZoneVector<Environment*> body_environments_;
};
// Tracks control flow for a block statement.
class BlockBuilder final : public ControlBuilder {
public:
explicit BlockBuilder(AstGraphBuilder* builder)
: ControlBuilder(builder), break_environment_(nullptr) {}
// Primitive control commands.
void BeginBlock();
void EndBlock();
// Primitive support for break.
void Break() final;
// Compound control commands for conditional break.
void BreakWhen(Node* condition, BranchHint = BranchHint::kNone);
void BreakUnless(Node* condition, BranchHint hint = BranchHint::kNone);
private:
Environment* break_environment_; // Environment after the block exits.
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_CONTROL_BUILDERS_H_
......@@ -98,12 +98,10 @@ class JSCallReduction {
};
JSBuiltinReducer::JSBuiltinReducer(Editor* editor, JSGraph* jsgraph,
Flags flags,
CompilationDependencies* dependencies,
Handle<Context> native_context)
: AdvancedReducer(editor),
dependencies_(dependencies),
flags_(flags),
jsgraph_(jsgraph),
native_context_(native_context),
type_cache_(TypeCache::Get()) {}
......
......@@ -6,7 +6,6 @@
#define V8_COMPILER_JS_BUILTIN_REDUCER_H_
#include "src/base/compiler-specific.h"
#include "src/base/flags.h"
#include "src/compiler/graph-reducer.h"
#include "src/globals.h"
......@@ -30,14 +29,7 @@ class TypeCache;
class V8_EXPORT_PRIVATE JSBuiltinReducer final
: public NON_EXPORTED_BASE(AdvancedReducer) {
public:
// Flags that control the mode of operation.
enum Flag {
kNoFlags = 0u,
kDeoptimizationEnabled = 1u << 0,
};
typedef base::Flags<Flag> Flags;
JSBuiltinReducer(Editor* editor, JSGraph* jsgraph, Flags flags,
JSBuiltinReducer(Editor* editor, JSGraph* jsgraph,
CompilationDependencies* dependencies,
Handle<Context> native_context);
~JSBuiltinReducer() final {}
......@@ -132,7 +124,6 @@ class V8_EXPORT_PRIVATE JSBuiltinReducer final
Node* ToNumber(Node* value);
Node* ToUint32(Node* value);
Flags flags() const { return flags_; }
Graph* graph() const;
Factory* factory() const;
JSGraph* jsgraph() const { return jsgraph_; }
......@@ -144,14 +135,11 @@ class V8_EXPORT_PRIVATE JSBuiltinReducer final
CompilationDependencies* dependencies() const { return dependencies_; }
CompilationDependencies* const dependencies_;
Flags const flags_;
JSGraph* const jsgraph_;
Handle<Context> const native_context_;
TypeCache const& type_cache_;
};
DEFINE_OPERATORS_FOR_FLAGS(JSBuiltinReducer::Flags)
} // namespace compiler
} // namespace internal
} // namespace v8
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/js-frame-specialization.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/linkage.h"
#include "src/frames-inl.h"
namespace v8 {
namespace internal {
namespace compiler {
Reduction JSFrameSpecialization::Reduce(Node* node) {
switch (node->opcode()) {
case IrOpcode::kOsrValue:
return ReduceOsrValue(node);
case IrOpcode::kParameter:
return ReduceParameter(node);
default:
break;
}
return NoChange();
}
Reduction JSFrameSpecialization::ReduceOsrValue(Node* node) {
// JSFrameSpecialization should never run on interpreted frames, since the
// code below assumes standard stack frame layouts.
DCHECK(!frame()->is_interpreted());
DCHECK_EQ(IrOpcode::kOsrValue, node->opcode());
Handle<Object> value;
int index = OsrValueIndexOf(node->op());
int const parameters_count = frame()->ComputeParametersCount() + 1;
if (index == Linkage::kOsrContextSpillSlotIndex) {
value = handle(frame()->context(), isolate());
} else if (index >= parameters_count) {
value = handle(frame()->GetExpression(index - parameters_count), isolate());
} else {
// The OsrValue index 0 is the receiver.
value =
handle(index ? frame()->GetParameter(index - 1) : frame()->receiver(),
isolate());
}
return Replace(jsgraph()->Constant(value));
}
Reduction JSFrameSpecialization::ReduceParameter(Node* node) {
DCHECK_EQ(IrOpcode::kParameter, node->opcode());
Handle<Object> value;
int const index = ParameterIndexOf(node->op());
int const parameters_count = frame()->ComputeParametersCount() + 1;
if (index == Linkage::kJSCallClosureParamIndex) {
// The Parameter index references the closure.
value = handle(frame()->function(), isolate());
} else if (index == Linkage::GetJSCallArgCountParamIndex(parameters_count)) {
// The Parameter index references the parameter count.
value = handle(Smi::FromInt(parameters_count - 1), isolate());
} else if (index == Linkage::GetJSCallContextParamIndex(parameters_count)) {
// The Parameter index references the context.
value = handle(frame()->context(), isolate());
} else {
// The Parameter index 0 is the receiver.
value =
handle(index ? frame()->GetParameter(index - 1) : frame()->receiver(),
isolate());
}
return Replace(jsgraph()->Constant(value));
}
Isolate* JSFrameSpecialization::isolate() const { return jsgraph()->isolate(); }
} // namespace compiler
} // namespace internal
} // namespace v8
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_JS_FRAME_SPECIALIZATION_H_
#define V8_COMPILER_JS_FRAME_SPECIALIZATION_H_
#include "src/compiler/graph-reducer.h"
namespace v8 {
namespace internal {
// Forward declarations.
class JavaScriptFrame;
namespace compiler {
// Forward declarations.
class JSGraph;
class JSFrameSpecialization final : public AdvancedReducer {
public:
JSFrameSpecialization(Editor* editor, JavaScriptFrame const* frame,
JSGraph* jsgraph)
: AdvancedReducer(editor), frame_(frame), jsgraph_(jsgraph) {}
~JSFrameSpecialization() final {}
const char* reducer_name() const override { return "JSFrameSpecialization"; }
Reduction Reduce(Node* node) final;
private:
Reduction ReduceOsrValue(Node* node);
Reduction ReduceParameter(Node* node);
Isolate* isolate() const;
JavaScriptFrame const* frame() const { return frame_; }
JSGraph* jsgraph() const { return jsgraph_; }
JavaScriptFrame const* const frame_;
JSGraph* const jsgraph_;
DISALLOW_COPY_AND_ASSIGN(JSFrameSpecialization);
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_JS_FRAME_SPECIALIZATION_H_
......@@ -438,14 +438,6 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
// Determine the call target.
if (!DetermineCallTarget(node, shared_info)) return NoChange();
// Inlining is only supported in the bytecode pipeline.
if (!info_->is_optimizing_from_bytecode()) {
TRACE("Not inlining %s into %s due to use of the deprecated pipeline\n",
shared_info->DebugName()->ToCString().get(),
info_->shared_info()->DebugName()->ToCString().get());
return NoChange();
}
// Function must be inlineable.
if (!shared_info->IsInlineable()) {
TRACE("Not inlining %s into %s because callee is not inlineable\n",
......
......@@ -20,9 +20,8 @@ namespace v8 {
namespace internal {
namespace compiler {
JSIntrinsicLowering::JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph,
DeoptimizationMode mode)
: AdvancedReducer(editor), jsgraph_(jsgraph), mode_(mode) {}
JSIntrinsicLowering::JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph)
: AdvancedReducer(editor), jsgraph_(jsgraph) {}
Reduction JSIntrinsicLowering::Reduce(Node* node) {
if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange();
......@@ -134,7 +133,6 @@ Reduction JSIntrinsicLowering::ReduceDebugIsActive(Node* node) {
}
Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
if (mode() != kDeoptimizationEnabled) return NoChange();
Node* const frame_state = NodeProperties::GetFrameStateInput(node);
Node* const effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node);
......
......@@ -31,10 +31,7 @@ class SimplifiedOperatorBuilder;
class V8_EXPORT_PRIVATE JSIntrinsicLowering final
: public NON_EXPORTED_BASE(AdvancedReducer) {
public:
enum DeoptimizationMode { kDeoptimizationEnabled, kDeoptimizationDisabled };
JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph,
DeoptimizationMode mode);
JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph);
~JSIntrinsicLowering() final {}
const char* reducer_name() const override { return "JSIntrinsicLowering"; }
......@@ -96,10 +93,8 @@ class V8_EXPORT_PRIVATE JSIntrinsicLowering final
CommonOperatorBuilder* common() const;
JSOperatorBuilder* javascript() const;
SimplifiedOperatorBuilder* simplified() const;
DeoptimizationMode mode() const { return mode_; }
JSGraph* const jsgraph_;
DeoptimizationMode const mode_;
};
} // namespace compiler
......
This diff is collapsed.
......@@ -6,7 +6,6 @@
#define V8_COMPILER_JS_TYPED_LOWERING_H_
#include "src/base/compiler-specific.h"
#include "src/base/flags.h"
#include "src/compiler/graph-reducer.h"
#include "src/compiler/opcodes.h"
#include "src/globals.h"
......@@ -31,15 +30,8 @@ class TypeCache;
class V8_EXPORT_PRIVATE JSTypedLowering final
: public NON_EXPORTED_BASE(AdvancedReducer) {
public:
// Flags that control the mode of operation.
enum Flag {
kNoFlags = 0u,
kDeoptimizationEnabled = 1u << 0,
};
typedef base::Flags<Flag> Flags;
JSTypedLowering(Editor* editor, CompilationDependencies* dependencies,
Flags flags, JSGraph* jsgraph, Zone* zone);
JSGraph* jsgraph, Zone* zone);
~JSTypedLowering() final {}
const char* reducer_name() const override { return "JSTypedLowering"; }
......@@ -106,10 +98,8 @@ class V8_EXPORT_PRIVATE JSTypedLowering final
CommonOperatorBuilder* common() const;
SimplifiedOperatorBuilder* simplified() const;
CompilationDependencies* dependencies() const;
Flags flags() const { return flags_; }
CompilationDependencies* dependencies_;
Flags flags_;
JSGraph* jsgraph_;
Type* empty_string_type_;
Type* shifted_int32_ranges_[4];
......@@ -117,8 +107,6 @@ class V8_EXPORT_PRIVATE JSTypedLowering final
TypeCache const& type_cache_;
};
DEFINE_OPERATORS_FOR_FLAGS(JSTypedLowering::Flags)
} // namespace compiler
} // namespace internal
} // namespace v8
......
This diff is collapsed.
......@@ -6,77 +6,6 @@
#define V8_COMPILER_OSR_H_
#include "src/zone/zone.h"
// TODO(6409) This phase (and then the below explanations) are now only used
// when osring from the ast graph builder. When using Ignition bytecode, the OSR
// implementation is integrated directly to the graph building phase.
// TurboFan structures OSR graphs in a way that separates almost all phases of
// compilation from OSR implementation details. This is accomplished with
// special control nodes that are added at graph building time. In particular,
// the graph is built in such a way that typing still computes the best types
// and optimizations and lowering work unchanged. All that remains is to
// deconstruct the OSR artifacts before scheduling and code generation.
// Graphs built for OSR from the AstGraphBuilder are structured as follows:
// Start
// +-------------------^^-----+
// | |
// OsrNormalEntry OsrLoopEntry <-------------+
// | | |
// control flow before loop | A OsrValue
// | | | |
// | +------------------------+ | +-------+
// | | +-------------+ | | +--------+
// | | | | | | | |
// ( Loop )<-----------|------------------ ( phi ) |
// | | |
// loop body | backedge(s) |
// | | | |
// | +--------------+ B <-----+
// |
// end
// The control structure expresses the relationship that the loop has a separate
// entrypoint which corresponds to entering the loop directly from the middle
// of unoptimized code.
// Similarly, the values that come in from unoptimized code are represented with
// {OsrValue} nodes that merge into any phis associated with the OSR loop.
// In the above diagram, nodes {A} and {B} represent values in the "normal"
// graph that correspond to the values of those phis before the loop and on any
// backedges, respectively.
// To deconstruct OSR, we simply replace the uses of the {OsrNormalEntry}
// control node with {Dead} and {OsrLoopEntry} with start and run the
// {ControlReducer}. Control reduction propagates the dead control forward,
// essentially "killing" all the code before the OSR loop. The entrypoint to the
// loop corresponding to the "normal" entry path will also be removed, as well
// as the inputs to the loop phis, resulting in the reduced graph:
// Start
// Dead |^-------------------------+
// | | |
// | | |
// | | |
// disconnected, dead | A=dead OsrValue
// | |
// +------------------+ +------+
// | +-------------+ | +--------+
// | | | | | |
// ( Loop )<-----------|------------------ ( phi ) |
// | | |
// loop body | backedge(s) |
// | | | |
// | +--------------+ B <-----+
// |
// end
// Other than the presences of the OsrValue nodes, this is a normal, schedulable
// graph. OsrValue nodes are handled specially in the instruction selector to
// simply load from the unoptimized frame.
// For nested OSR loops, loop peeling must first be applied as many times as
// necessary in order to bring the OSR loop up to the top level (i.e. to be
// an outer loop).
namespace v8 {
namespace internal {
......@@ -85,10 +14,7 @@ class CompilationInfo;
namespace compiler {
class JSGraph;
class CommonOperatorBuilder;
class Frame;
class Linkage;
// Encapsulates logic relating to OSR compilations as well has handles some
// details of the frame layout.
......@@ -96,11 +22,6 @@ class OsrHelper {
public:
explicit OsrHelper(CompilationInfo* info);
// Deconstructs the artificial {OsrNormalEntry} and rewrites the graph so
// that only the path corresponding to {OsrLoopEntry} remains.
void Deconstruct(CompilationInfo* info, JSGraph* jsgraph,
CommonOperatorBuilder* common, Zone* tmp_zone);
// Prepares the frame w.r.t. OSR.
void SetupFrame(Frame* frame);
......@@ -109,7 +30,7 @@ class OsrHelper {
// Returns the environment index of the first stack slot.
static int FirstStackSlotIndex(int parameter_count) {
// n.b. unlike Crankshaft, TurboFan environments do not contain the context.
// TurboFan environments do not contain the context.
return 1 + parameter_count; // receiver + params
}
......
This diff is collapsed.
......@@ -17,10 +17,9 @@ namespace compiler {
TypedOptimization::TypedOptimization(Editor* editor,
CompilationDependencies* dependencies,
Flags flags, JSGraph* jsgraph)
JSGraph* jsgraph)
: AdvancedReducer(editor),
dependencies_(dependencies),
flags_(flags),
jsgraph_(jsgraph),
true_type_(Type::HeapConstant(factory()->true_value(), graph()->zone())),
false_type_(
......@@ -212,11 +211,7 @@ Reduction TypedOptimization::ReduceLoadField(Node* node) {
Handle<Map> object_map;
if (GetStableMapFromObjectType(object_type).ToHandle(&object_map)) {
if (object_map->CanTransition()) {
if (flags() & kDeoptimizationEnabled) {
dependencies()->AssumeMapStable(object_map);
} else {
return NoChange();
}
dependencies()->AssumeMapStable(object_map);
}
Node* const value = jsgraph()->HeapConstant(object_map);
ReplaceWithValue(node, value);
......
......@@ -6,7 +6,6 @@
#define V8_COMPILER_TYPED_OPTIMIZATION_H_
#include "src/base/compiler-specific.h"
#include "src/base/flags.h"
#include "src/compiler/graph-reducer.h"
#include "src/globals.h"
......@@ -28,15 +27,8 @@ class TypeCache;
class V8_EXPORT_PRIVATE TypedOptimization final
: public NON_EXPORTED_BASE(AdvancedReducer) {
public:
// Flags that control the mode of operation.
enum Flag {
kNoFlags = 0u,
kDeoptimizationEnabled = 1u << 0,
};
typedef base::Flags<Flag> Flags;
TypedOptimization(Editor* editor, CompilationDependencies* dependencies,
Flags flags, JSGraph* jsgraph);
JSGraph* jsgraph);
~TypedOptimization();
const char* reducer_name() const override { return "TypedOptimization"; }
......@@ -61,14 +53,12 @@ class V8_EXPORT_PRIVATE TypedOptimization final
CompilationDependencies* dependencies() const { return dependencies_; }
Factory* factory() const;
Flags flags() const { return flags_; }
Graph* graph() const;
Isolate* isolate() const;
JSGraph* jsgraph() const { return jsgraph_; }
SimplifiedOperatorBuilder* simplified() const;
CompilationDependencies* const dependencies_;
Flags const flags_;
JSGraph* const jsgraph_;
Type* const true_type_;
Type* const false_type_;
......@@ -77,8 +67,6 @@ class V8_EXPORT_PRIVATE TypedOptimization final
DISALLOW_COPY_AND_ASSIGN(TypedOptimization);
};
DEFINE_OPERATORS_FOR_FLAGS(TypedOptimization::Flags)
} // namespace compiler
} // namespace internal
} // namespace v8
......
......@@ -443,7 +443,6 @@ DEFINE_BOOL(turbo_inline_array_builtins, true,
DEFINE_BOOL(turbo_load_elimination, true, "enable load elimination in TurboFan")
DEFINE_BOOL(trace_turbo_load_elimination, false,
"trace TurboFan load elimination")
DEFINE_BOOL(loop_assignment_analysis, true, "perform loop assignment analysis")
DEFINE_BOOL(turbo_profiling, false, "enable profiling in TurboFan")
DEFINE_BOOL(turbo_verify_allocation, DEBUG_BOOL,
"verify register allocation in TurboFan")
......
This diff is collapsed.
......@@ -37,7 +37,6 @@ v8_executable("cctest") {
"compiler/test-jump-threading.cc",
"compiler/test-linkage.cc",
"compiler/test-loop-analysis.cc",
"compiler/test-loop-assignment-analysis.cc",
"compiler/test-machine-operator-reducer.cc",
"compiler/test-multiple-return.cc",
"compiler/test-node.cc",
......
......@@ -53,7 +53,6 @@
'compiler/test-js-typed-lowering.cc',
'compiler/test-jump-threading.cc',
'compiler/test-linkage.cc',
'compiler/test-loop-assignment-analysis.cc',
'compiler/test-loop-analysis.cc',
'compiler/test-machine-operator-reducer.cc',
'compiler/test-multiple-return.cc',
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment