summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/pipeline.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/pipeline.cc')
-rw-r--r--deps/v8/src/compiler/pipeline.cc204
1 files changed, 122 insertions, 82 deletions
diff --git a/deps/v8/src/compiler/pipeline.cc b/deps/v8/src/compiler/pipeline.cc
index ceff8d660b..4d6aacd78a 100644
--- a/deps/v8/src/compiler/pipeline.cc
+++ b/deps/v8/src/compiler/pipeline.cc
@@ -12,7 +12,6 @@
#include "src/compiler/ast-graph-builder.h"
#include "src/compiler/ast-loop-assignment-analyzer.h"
#include "src/compiler/basic-block-instrumentor.h"
-#include "src/compiler/binary-operator-reducer.h"
#include "src/compiler/branch-elimination.h"
#include "src/compiler/bytecode-graph-builder.h"
#include "src/compiler/change-lowering.h"
@@ -20,6 +19,8 @@
#include "src/compiler/common-operator-reducer.h"
#include "src/compiler/control-flow-optimizer.h"
#include "src/compiler/dead-code-elimination.h"
+#include "src/compiler/escape-analysis.h"
+#include "src/compiler/escape-analysis-reducer.h"
#include "src/compiler/frame-elider.h"
#include "src/compiler/graph-replay.h"
#include "src/compiler/graph-trimmer.h"
@@ -28,6 +29,7 @@
#include "src/compiler/instruction.h"
#include "src/compiler/instruction-selector.h"
#include "src/compiler/js-builtin-reducer.h"
+#include "src/compiler/js-call-reducer.h"
#include "src/compiler/js-context-relaxation.h"
#include "src/compiler/js-context-specialization.h"
#include "src/compiler/js-frame-specialization.h"
@@ -55,6 +57,7 @@
#include "src/compiler/simplified-operator.h"
#include "src/compiler/simplified-operator-reducer.h"
#include "src/compiler/tail-call-optimization.h"
+#include "src/compiler/type-hint-analyzer.h"
#include "src/compiler/typer.h"
#include "src/compiler/value-numbering-reducer.h"
#include "src/compiler/verifier.h"
@@ -102,7 +105,7 @@ class PipelineData {
source_positions_.Reset(new SourcePositionTable(graph_));
simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_);
machine_ = new (graph_zone_) MachineOperatorBuilder(
- graph_zone_, kMachPtr,
+ graph_zone_, MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags());
common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_);
javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_);
@@ -197,6 +200,12 @@ class PipelineData {
CommonOperatorBuilder* common() const { return common_; }
JSOperatorBuilder* javascript() const { return javascript_; }
JSGraph* jsgraph() const { return jsgraph_; }
+ MaybeHandle<Context> native_context() const {
+ if (info()->is_native_context_specializing()) {
+ return handle(info()->native_context(), isolate());
+ }
+ return MaybeHandle<Context>();
+ }
LoopAssignmentAnalysis* loop_assignment() const { return loop_assignment_; }
void set_loop_assignment(LoopAssignmentAnalysis* loop_assignment) {
@@ -204,6 +213,12 @@ class PipelineData {
loop_assignment_ = loop_assignment;
}
+ TypeHintAnalysis* type_hint_analysis() const { return type_hint_analysis_; }
+ void set_type_hint_analysis(TypeHintAnalysis* type_hint_analysis) {
+ DCHECK_NULL(type_hint_analysis_);
+ type_hint_analysis_ = type_hint_analysis;
+ }
+
Schedule* schedule() const { return schedule_; }
void set_schedule(Schedule* schedule) {
DCHECK(!schedule_);
@@ -228,6 +243,7 @@ class PipelineData {
graph_zone_ = nullptr;
graph_ = nullptr;
loop_assignment_ = nullptr;
+ type_hint_analysis_ = nullptr;
simplified_ = nullptr;
machine_ = nullptr;
common_ = nullptr;
@@ -267,12 +283,12 @@ class PipelineData {
DCHECK(register_allocation_data_ == nullptr);
int fixed_frame_size = 0;
if (descriptor != nullptr) {
- fixed_frame_size = (descriptor->kind() == CallDescriptor::kCallAddress)
+ fixed_frame_size = (descriptor->IsCFunctionCall())
? StandardFrameConstants::kFixedSlotCountAboveFp +
StandardFrameConstants::kCPSlotCount
: StandardFrameConstants::kFixedSlotCount;
}
- frame_ = new (instruction_zone()) Frame(fixed_frame_size);
+ frame_ = new (instruction_zone()) Frame(fixed_frame_size, descriptor);
register_allocation_data_ = new (register_allocation_zone())
RegisterAllocationData(config, register_allocation_zone(), frame(),
sequence(), debug_name);
@@ -288,13 +304,14 @@ class PipelineData {
Handle<Code> code_;
// All objects in the following group of fields are allocated in graph_zone_.
- // They are all set to NULL when the graph_zone_ is destroyed.
+ // They are all set to nullptr when the graph_zone_ is destroyed.
ZonePool::Scope graph_zone_scope_;
Zone* graph_zone_;
Graph* graph_;
// TODO(dcarney): make this into a ZoneObject.
base::SmartPointer<SourcePositionTable> source_positions_;
LoopAssignmentAnalysis* loop_assignment_;
+ TypeHintAnalysis* type_hint_analysis_ = nullptr;
SimplifiedOperatorBuilder* simplified_;
MachineOperatorBuilder* machine_;
CommonOperatorBuilder* common_;
@@ -303,7 +320,8 @@ class PipelineData {
Schedule* schedule_;
// All objects in the following group of fields are allocated in
- // instruction_zone_. They are all set to NULL when the instruction_zone_ is
+ // instruction_zone_. They are all set to nullptr when the instruction_zone_
+ // is
// destroyed.
ZonePool::Scope instruction_zone_scope_;
Zone* instruction_zone_;
@@ -311,7 +329,7 @@ class PipelineData {
Frame* frame_;
// All objects in the following group of fields are allocated in
- // register_allocation_zone_. They are all set to NULL when the zone is
+ // register_allocation_zone_. They are all set to nullptr when the zone is
// destroyed.
ZonePool::Scope register_allocation_zone_scope_;
Zone* register_allocation_zone_;
@@ -332,7 +350,7 @@ struct TurboCfgFile : public std::ofstream {
void TraceSchedule(CompilationInfo* info, Schedule* schedule) {
if (FLAG_trace_turbo) {
- FILE* json_file = OpenVisualizerLogFile(info, NULL, "json", "a+");
+ FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+");
if (json_file != nullptr) {
OFStream json_of(json_file);
json_of << "{\"name\":\"Schedule\",\"type\":\"schedule\",\"data\":\"";
@@ -357,8 +375,10 @@ class AstGraphBuilderWithPositions final : public AstGraphBuilder {
AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
JSGraph* jsgraph,
LoopAssignmentAnalysis* loop_assignment,
+ TypeHintAnalysis* type_hint_analysis,
SourcePositionTable* source_positions)
- : AstGraphBuilder(local_zone, info, jsgraph, loop_assignment),
+ : AstGraphBuilder(local_zone, info, jsgraph, loop_assignment,
+ type_hint_analysis),
source_positions_(source_positions),
start_position_(info->shared_info()->start_position()) {}
@@ -470,6 +490,18 @@ struct LoopAssignmentAnalysisPhase {
};
+struct TypeHintAnalysisPhase {
+ static const char* phase_name() { return "type hint analysis"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ TypeHintAnalyzer analyzer(data->graph_zone());
+ Handle<Code> code(data->info()->shared_info()->code(), data->isolate());
+ TypeHintAnalysis* type_hint_analysis = analyzer.Analyze(code);
+ data->set_type_hint_analysis(type_hint_analysis);
+ }
+};
+
+
struct GraphBuilderPhase {
static const char* phase_name() { return "graph builder"; }
@@ -484,7 +516,7 @@ struct GraphBuilderPhase {
} else {
AstGraphBuilderWithPositions graph_builder(
temp_zone, data->info(), data->jsgraph(), data->loop_assignment(),
- data->source_positions());
+ data->type_hint_analysis(), data->source_positions());
succeeded = graph_builder.CreateGraph(stack_check);
}
@@ -495,8 +527,8 @@ struct GraphBuilderPhase {
};
-struct NativeContextSpecializationPhase {
- static const char* phase_name() { return "native context specialization"; }
+struct InliningPhase {
+ static const char* phase_name() { return "inlining"; }
void Run(PipelineData* data, Zone* temp_zone) {
JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
@@ -504,46 +536,30 @@ struct NativeContextSpecializationPhase {
data->common());
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
data->common(), data->machine());
+ JSCallReducer call_reducer(data->jsgraph(),
+ data->info()->is_deoptimization_enabled()
+ ? JSCallReducer::kDeoptimizationEnabled
+ : JSCallReducer::kNoFlags,
+ data->native_context());
+ JSContextSpecialization context_specialization(
+ &graph_reducer, data->jsgraph(),
+ data->info()->is_function_context_specializing()
+ ? data->info()->context()
+ : MaybeHandle<Context>());
+ JSFrameSpecialization frame_specialization(data->info()->osr_frame(),
+ data->jsgraph());
JSGlobalObjectSpecialization global_object_specialization(
&graph_reducer, data->jsgraph(),
data->info()->is_deoptimization_enabled()
? JSGlobalObjectSpecialization::kDeoptimizationEnabled
: JSGlobalObjectSpecialization::kNoFlags,
- handle(data->info()->global_object(), data->isolate()),
- data->info()->dependencies());
+ data->native_context(), data->info()->dependencies());
JSNativeContextSpecialization native_context_specialization(
&graph_reducer, data->jsgraph(),
data->info()->is_deoptimization_enabled()
? JSNativeContextSpecialization::kDeoptimizationEnabled
: JSNativeContextSpecialization::kNoFlags,
- handle(data->info()->global_object()->native_context(),
- data->isolate()),
- data->info()->dependencies(), temp_zone);
- AddReducer(data, &graph_reducer, &dead_code_elimination);
- AddReducer(data, &graph_reducer, &common_reducer);
- AddReducer(data, &graph_reducer, &global_object_specialization);
- AddReducer(data, &graph_reducer, &native_context_specialization);
- graph_reducer.ReduceGraph();
- }
-};
-
-
-struct InliningPhase {
- static const char* phase_name() { return "inlining"; }
-
- void Run(PipelineData* data, Zone* temp_zone) {
- JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
- DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
- data->common());
- CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
- data->common(), data->machine());
- JSContextSpecialization context_specialization(
- &graph_reducer, data->jsgraph(),
- data->info()->is_function_context_specializing()
- ? data->info()->context()
- : MaybeHandle<Context>());
- JSFrameSpecialization frame_specialization(data->info()->osr_frame(),
- data->jsgraph());
+ data->native_context(), data->info()->dependencies(), temp_zone);
JSInliningHeuristic inlining(&graph_reducer,
data->info()->is_inlining_enabled()
? JSInliningHeuristic::kGeneralInlining
@@ -554,7 +570,10 @@ struct InliningPhase {
if (data->info()->is_frame_specializing()) {
AddReducer(data, &graph_reducer, &frame_specialization);
}
+ AddReducer(data, &graph_reducer, &global_object_specialization);
+ AddReducer(data, &graph_reducer, &native_context_specialization);
AddReducer(data, &graph_reducer, &context_specialization);
+ AddReducer(data, &graph_reducer, &call_reducer);
AddReducer(data, &graph_reducer, &inlining);
graph_reducer.ReduceGraph();
}
@@ -591,11 +610,16 @@ struct TypedLoweringPhase {
data->common());
LoadElimination load_elimination(&graph_reducer);
JSBuiltinReducer builtin_reducer(&graph_reducer, data->jsgraph());
+ JSTypedLowering::Flags typed_lowering_flags = JSTypedLowering::kNoFlags;
+ if (data->info()->is_deoptimization_enabled()) {
+ typed_lowering_flags |= JSTypedLowering::kDeoptimizationEnabled;
+ }
+ if (data->info()->shared_info()->HasBytecodeArray()) {
+ typed_lowering_flags |= JSTypedLowering::kDisableBinaryOpReduction;
+ }
JSTypedLowering typed_lowering(&graph_reducer, data->info()->dependencies(),
- data->info()->is_deoptimization_enabled()
- ? JSTypedLowering::kDeoptimizationEnabled
- : JSTypedLowering::kNoFlags,
- data->jsgraph(), temp_zone);
+ typed_lowering_flags, data->jsgraph(),
+ temp_zone);
JSIntrinsicLowering intrinsic_lowering(
&graph_reducer, data->jsgraph(),
data->info()->is_deoptimization_enabled()
@@ -630,6 +654,22 @@ struct BranchEliminationPhase {
};
+struct EscapeAnalysisPhase {
+ static const char* phase_name() { return "escape analysis"; }
+
+ void Run(PipelineData* data, Zone* temp_zone) {
+ EscapeAnalysis escape_analysis(data->graph(), data->jsgraph()->common(),
+ temp_zone);
+ escape_analysis.Run();
+ JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
+ EscapeAnalysisReducer escape_reducer(&graph_reducer, data->jsgraph(),
+ &escape_analysis, temp_zone);
+ AddReducer(data, &graph_reducer, &escape_reducer);
+ graph_reducer.ReduceGraph();
+ }
+};
+
+
struct SimplifiedLoweringPhase {
static const char* phase_name() { return "simplified lowering"; }
@@ -645,14 +685,11 @@ struct SimplifiedLoweringPhase {
MachineOperatorReducer machine_reducer(data->jsgraph());
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
data->common(), data->machine());
- BinaryOperatorReducer binary_reducer(&graph_reducer, data->graph(),
- data->common(), data->machine());
AddReducer(data, &graph_reducer, &dead_code_elimination);
AddReducer(data, &graph_reducer, &simple_reducer);
AddReducer(data, &graph_reducer, &value_numbering);
AddReducer(data, &graph_reducer, &machine_reducer);
AddReducer(data, &graph_reducer, &common_reducer);
- AddReducer(data, &graph_reducer, &binary_reducer);
graph_reducer.ReduceGraph();
}
};
@@ -722,7 +759,7 @@ struct StressLoopPeelingPhase {
// Peel the first outer loop for testing.
// TODO(titzer): peel all loops? the N'th loop? Innermost loops?
LoopTree* loop_tree = LoopFinder::BuildLoopTree(data->graph(), temp_zone);
- if (loop_tree != NULL && loop_tree->outer_loops().size() > 0) {
+ if (loop_tree != nullptr && loop_tree->outer_loops().size() > 0) {
LoopPeeler::Peel(data->graph(), data->common(), loop_tree,
loop_tree->outer_loops()[0], temp_zone);
}
@@ -969,16 +1006,8 @@ struct PrintGraphPhase {
CompilationInfo* info = data->info();
Graph* graph = data->graph();
- { // Print dot.
- FILE* dot_file = OpenVisualizerLogFile(info, phase, "dot", "w+");
- if (dot_file == nullptr) return;
- OFStream dot_of(dot_file);
- dot_of << AsDOT(*graph);
- fclose(dot_file);
- }
-
{ // Print JSON.
- FILE* json_file = OpenVisualizerLogFile(info, NULL, "json", "a+");
+ FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+");
if (json_file == nullptr) return;
OFStream json_of(json_file);
json_of << "{\"name\":\"" << phase << "\",\"type\":\"graph\",\"data\":"
@@ -1007,7 +1036,7 @@ struct VerifyGraphPhase {
void Pipeline::BeginPhaseKind(const char* phase_kind_name) {
- if (data_->pipeline_statistics() != NULL) {
+ if (data_->pipeline_statistics() != nullptr) {
data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name);
}
}
@@ -1040,7 +1069,7 @@ Handle<Code> Pipeline::GenerateCode() {
}
if (FLAG_trace_turbo) {
- FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "w+");
+ FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "w+");
if (json_file != nullptr) {
OFStream json_of(json_file);
Handle<Script> script = info()->script();
@@ -1084,6 +1113,10 @@ Handle<Code> Pipeline::GenerateCode() {
Run<LoopAssignmentAnalysisPhase>();
}
+ if (info()->is_typing_enabled()) {
+ Run<TypeHintAnalysisPhase>();
+ }
+
Run<GraphBuilderPhase>();
if (data.compilation_failed()) return Handle<Code>::null();
RunPrintAndVerify("Initial untyped", true);
@@ -1094,12 +1127,6 @@ Handle<Code> Pipeline::GenerateCode() {
RunPrintAndVerify("OSR deconstruction", true);
}
- // Perform native context specialization (if enabled).
- if (info()->is_native_context_specializing()) {
- Run<NativeContextSpecializationPhase>();
- RunPrintAndVerify("Native context specialized", true);
- }
-
// Perform function context specialization and inlining (if enabled).
Run<InliningPhase>();
RunPrintAndVerify("Inlined", true);
@@ -1120,7 +1147,7 @@ Handle<Code> Pipeline::GenerateCode() {
info()->is_deoptimization_enabled()
? Typer::kDeoptimizationEnabled
: Typer::kNoFlags,
- info()->dependencies(), info()->function_type()));
+ info()->dependencies()));
Run<TyperPhase>(typer.get());
RunPrintAndVerify("Typed");
}
@@ -1137,6 +1164,11 @@ Handle<Code> Pipeline::GenerateCode() {
RunPrintAndVerify("Loop peeled");
}
+ if (FLAG_turbo_escape) {
+ Run<EscapeAnalysisPhase>();
+ RunPrintAndVerify("Escape Analysed");
+ }
+
// Lower simplified operators and insert changes.
Run<SimplifiedLoweringPhase>();
RunPrintAndVerify("Lowered simplified");
@@ -1177,10 +1209,13 @@ Handle<Code> Pipeline::GenerateCode() {
}
-Handle<Code> Pipeline::GenerateCodeForInterpreter(
- Isolate* isolate, CallDescriptor* call_descriptor, Graph* graph,
- Schedule* schedule, const char* bytecode_name) {
- CompilationInfo info(bytecode_name, isolate, graph->zone());
+Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate,
+ CallDescriptor* call_descriptor,
+ Graph* graph, Schedule* schedule,
+ Code::Kind kind,
+ const char* debug_name) {
+ CompilationInfo info(debug_name, isolate, graph->zone());
+ info.set_output_code_kind(kind);
// Construct a pipeline for scheduling and code generation.
ZonePool zone_pool;
@@ -1188,21 +1223,24 @@ Handle<Code> Pipeline::GenerateCodeForInterpreter(
base::SmartPointer<PipelineStatistics> pipeline_statistics;
if (FLAG_turbo_stats) {
pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool));
- pipeline_statistics->BeginPhaseKind("interpreter handler codegen");
+ pipeline_statistics->BeginPhaseKind("stub codegen");
}
+
+ Pipeline pipeline(&info);
+ pipeline.data_ = &data;
+ DCHECK_NOT_NULL(data.schedule());
+
if (FLAG_trace_turbo) {
- FILE* json_file = OpenVisualizerLogFile(&info, NULL, "json", "w+");
+ FILE* json_file = OpenVisualizerLogFile(&info, nullptr, "json", "w+");
if (json_file != nullptr) {
OFStream json_of(json_file);
json_of << "{\"function\":\"" << info.GetDebugName().get()
<< "\", \"source\":\"\",\n\"phases\":[";
fclose(json_file);
}
+ pipeline.Run<PrintGraphPhase>("Machine");
}
- Pipeline pipeline(&info);
- pipeline.data_ = &data;
- pipeline.RunPrintAndVerify("Machine", true);
return pipeline.ScheduleAndGenerateCode(call_descriptor);
}
@@ -1262,7 +1300,7 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
if (data->schedule() == nullptr) Run<ComputeSchedulePhase>();
TraceSchedule(data->info(), data->schedule());
- BasicBlockProfiler::Data* profiler_data = NULL;
+ BasicBlockProfiler::Data* profiler_data = nullptr;
if (FLAG_turbo_profiling) {
profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(),
data->schedule());
@@ -1311,10 +1349,10 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
Run<GenerateCodePhase>(&linkage);
Handle<Code> code = data->code();
- if (profiler_data != NULL) {
+ if (profiler_data != nullptr) {
#if ENABLE_DISASSEMBLER
std::ostringstream os;
- code->Disassemble(NULL, os);
+ code->Disassemble(nullptr, os);
profiler_data->SetCode(&os);
#endif
}
@@ -1323,14 +1361,14 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
v8::internal::CodeGenerator::PrintCode(code, info());
if (FLAG_trace_turbo) {
- FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "a+");
+ FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+");
if (json_file != nullptr) {
OFStream json_of(json_file);
json_of
<< "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\"";
#if ENABLE_DISASSEMBLER
std::stringstream disassembly_stream;
- code->Disassemble(NULL, disassembly_stream);
+ code->Disassemble(nullptr, disassembly_stream);
std::string disassembly_string(disassembly_stream.str());
for (const auto& c : disassembly_string) {
json_of << AsEscapedUC16ForJSON(c);
@@ -1388,6 +1426,8 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
}
if (verifier != nullptr) {
CHECK(!data->register_allocation_data()->ExistsUseWithoutDefinition());
+ CHECK(data->register_allocation_data()
+ ->RangesDefinedInDeferredStayInDeferred());
}
if (FLAG_turbo_preprocess_ranges) {