Chromium Code Reviews| Index: runtime/vm/precompiler.cc |
| diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc |
| index 3ece322ca4df7b0cb5aa04bb94a289ac01c2dca9..c4ed57511809c4b0c099dc471386923a357445a7 100644 |
| --- a/runtime/vm/precompiler.cc |
| +++ b/runtime/vm/precompiler.cc |
| @@ -54,7 +54,7 @@ DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets"); |
| DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); |
| DEFINE_FLAG(int, max_speculative_inlining_attempts, 1, |
| "Max number of attempts with speculative inlining (precompilation only)"); |
| -DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations"); |
| +DEFINE_FLAG(int, precompiler_rounds, 2, "Number of precompiler iterations"); |
|
Vyacheslav Egorov (Google)
2016/05/12 11:18:55
We should check that this does not slow down Flutt
Florian Schneider
2016/05/12 11:37:17
Agree.
Current measurements shows 60% increase in
|
| DECLARE_FLAG(bool, allocation_sinking); |
| DECLARE_FLAG(bool, common_subexpression_elimination); |
| @@ -75,6 +75,33 @@ DECLARE_FLAG(bool, trace_irregexp); |
| #ifdef DART_PRECOMPILER |
| +class DartPrecompilationPipeline : public DartCompilationPipeline { |
| + public: |
| + DartPrecompilationPipeline() : result_type_(CompileType::None()) { } |
| + |
| + virtual void FinalizeCompilation(FlowGraph* flow_graph) { |
| + CompileType result_type = CompileType::None(); |
| + for (BlockIterator block_it = flow_graph->reverse_postorder_iterator(); |
| + !block_it.Done(); |
| + block_it.Advance()) { |
| + ForwardInstructionIterator it(block_it.Current()); |
| + for (; !it.Done(); it.Advance()) { |
| + ReturnInstr* return_instr = it.Current()->AsReturn(); |
| + if (return_instr != NULL) { |
| + result_type.Union(return_instr->InputAt(0)->Type()); |
| + } |
| + } |
| + } |
| + result_type_ = result_type; |
| + } |
| + |
| + CompileType result_type() { return result_type_; } |
| + |
| + private: |
| + CompileType result_type_; |
| +}; |
| + |
| + |
| class PrecompileParsedFunctionHelper : public ValueObject { |
| public: |
| PrecompileParsedFunctionHelper(ParsedFunction* parsed_function, |
| @@ -768,8 +795,8 @@ void Precompiler::AddField(const Field& field) { |
| THR_Print("Precompiling initializer for %s\n", field.ToCString()); |
| } |
| ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT); |
| - const Function& initializer = |
| - Function::Handle(Z, CompileStaticInitializer(field)); |
| + const Function& initializer = Function::Handle(Z, |
| + CompileStaticInitializer(field, /* compute_type = */ true)); |
| ASSERT(!initializer.IsNull()); |
| field.SetPrecompiledInitializer(initializer); |
| AddCalleesOf(initializer); |
| @@ -779,7 +806,8 @@ void Precompiler::AddField(const Field& field) { |
| } |
| -RawFunction* Precompiler::CompileStaticInitializer(const Field& field) { |
| +RawFunction* Precompiler::CompileStaticInitializer(const Field& field, |
| + bool compute_type) { |
| ASSERT(field.is_static()); |
| Thread* thread = Thread::Current(); |
| StackZone zone(thread); |
| @@ -787,12 +815,23 @@ RawFunction* Precompiler::CompileStaticInitializer(const Field& field) { |
| ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); |
| parsed_function->AllocateVariables(); |
| - DartCompilationPipeline pipeline; |
| + DartPrecompilationPipeline pipeline; |
| PrecompileParsedFunctionHelper helper(parsed_function, |
| /* optimized = */ true); |
| bool success = helper.Compile(&pipeline); |
| ASSERT(success); |
| + if (compute_type && field.is_final()) { |
| + intptr_t result_cid = pipeline.result_type().ToCid(); |
| + if (result_cid != kDynamicCid) { |
| + if (FLAG_trace_precompiler) { |
| + THR_Print("Setting guarded_cid of %s to %s\n", field.ToCString(), |
| + pipeline.result_type().ToCString()); |
| + } |
| + field.set_guarded_cid(result_cid); |
| + } |
| + } |
| + |
| if ((FLAG_disassemble || FLAG_disassemble_optimized) && |
| FlowGraphPrinter::ShouldPrint(parsed_function->function())) { |
| Disassembler::DisassembleCode(parsed_function->function(), |
| @@ -815,7 +854,7 @@ RawObject* Precompiler::EvaluateStaticInitializer(const Field& field) { |
| // remembering it because it won't be used again. |
| Function& initializer = Function::Handle(); |
| if (!field.HasPrecompiledInitializer()) { |
| - initializer = CompileStaticInitializer(field); |
| + initializer = CompileStaticInitializer(field, /* compute_type = */ false); |
| } else { |
| initializer ^= field.PrecompiledInitializer(); |
| } |
| @@ -876,7 +915,7 @@ RawObject* Precompiler::ExecuteOnce(SequenceNode* fragment) { |
| parsed_function->AllocateVariables(); |
| // Non-optimized code generator. |
| - DartCompilationPipeline pipeline; |
| + DartPrecompilationPipeline pipeline; |
| PrecompileParsedFunctionHelper helper(parsed_function, |
| /* optimized = */ false); |
| helper.Compile(&pipeline); |
| @@ -2579,7 +2618,7 @@ bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { |
| "CompileGraph"); |
| #endif // !PRODUCT |
| graph_compiler.CompileGraph(); |
| - pipeline->FinalizeCompilation(); |
| + pipeline->FinalizeCompilation(flow_graph); |
| } |
| { |
| #ifndef PRODUCT |