28 const char* lib_uri) {
105 auto install_code_fun = [&] {
111 thread->isolate_group()->RunWithStoppedMutators(install_code_fun,
113 return code.instructions();
117 std::initializer_list<CompilerPass::Id> passes) {
119 auto zone = thread->zone();
120 const bool optimized =
true;
125 const bool is_ssa = (flow_graph_ !=
nullptr);
126 if (flow_graph_ ==
nullptr) {
129 parsed_function_ =
new (zone)
131 pipeline->ParseFunction(parsed_function_);
140 flow_graph_ = pipeline->BuildFlowGraph(zone, parsed_function_,
141 ic_data_array_, osr_id, optimized);
157 speculative_policy_.get());
159 nullptr, flow_graph_, speculative_policy_.get());
166 if (passes.size() > 0) {
179 std::initializer_list<CompilerPass::Id> passes) {
181 speculative_policy_.get());
183 speculative_policy_.get());
196 CompilerPass::kSetOuterInliningId,
197 CompilerPass::kTypePropagation,
198 CompilerPass::kCanonicalize,
199 CompilerPass::kBranchSimplify,
200 CompilerPass::kIfConvert,
201 CompilerPass::kConstantPropagation,
202 CompilerPass::kTypePropagation,
203 CompilerPass::kSelectRepresentations_Final,
204 CompilerPass::kTypePropagation,
205 CompilerPass::kTryCatchOptimization,
206 CompilerPass::kEliminateEnvironments,
207 CompilerPass::kEliminateDeadPhis,
209 CompilerPass::kCanonicalize,
210 CompilerPass::kDelayAllocations,
211 CompilerPass::kEliminateWriteBarriers,
212 CompilerPass::kFinalizeGraph,
213 CompilerPass::kAllocateRegisters,
214 CompilerPass::kReorderBlocks,
220 const bool optimized =
true;
224#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32)
225 const intptr_t far_branch_level = 0;
227 const intptr_t far_branch_level = 1;
235 &assembler, flow_graph_, *parsed_function_, optimized,
242 const auto& deopt_info_array =
252 code.set_is_optimized(optimized);
253 code.set_owner(function_);
256 code.set_deopt_info_array(deopt_info_array);
278 EXPECT(deopt_info_array.IsNull() || deopt_info_array.Length() == 0);
282 if (FLAG_disassemble_optimized) {
290 std::vector<MatchCode> qcodes = match_codes;
293 for (
auto pos = qcodes.begin();
pos < qcodes.end();
pos++) {
294 pos = qcodes.insert(
pos, insert_before) + 1;
299 OS::PrintErr(
"ILMatcher: Matching the following graph\n");
305 for (
size_t i = 0;
i < qcodes.size(); ++
i) {
308 while (cursor->IsParallelMove()) {
309 cursor = cursor->
next();
314 MatchOpCodeToCString(qcodes[
i].opcode()),
318 auto next = MatchInternal(qcodes,
i, cursor);
319 if (
next ==
nullptr) {
326 if (capture !=
nullptr) {
331 if (cursor !=
nullptr) {
338Instruction* ILMatcher::MatchInternal(std::vector<MatchCode> match_codes,
343 auto branch = cursor->AsBranch();
344 if (branch ==
nullptr)
return nullptr;
345 return branch->true_successor();
348 auto branch = cursor->AsBranch();
349 if (branch ==
nullptr)
return nullptr;
350 return branch->false_successor();
352 if (opcode ==
kNop) {
356 return cursor->
next();
359 while (cursor !=
nullptr && cursor->IsParallelMove()) {
360 cursor = cursor->
next();
366 ASSERT((
i + 1) < match_codes.size());
368 if (cursor ==
nullptr)
return nullptr;
369 if (MatchInternal(match_codes,
i + 1, cursor) !=
nullptr) {
372 if (
auto as_goto = cursor->AsGoto()) {
373 cursor = as_goto->successor();
375 cursor = cursor->
next();
381 while (cursor !=
nullptr && cursor->IsDebugStepCheck()) {
382 cursor = cursor->
next();
387 if (opcode == kMatchAndMoveGoto) {
388 if (
auto goto_instr = cursor->AsGoto()) {
389 return goto_instr->successor();
394#define EMIT_CASE(Instruction, _) \
395 case kMatch##Instruction: { \
396 if (cursor->Is##Instruction()) { \
401 case kMatchAndMove##Instruction: { \
402 if (cursor->Is##Instruction()) { \
403 return cursor->next(); \
407 case kMatchAndMoveOptional##Instruction: { \
408 if (cursor->Is##Instruction()) { \
409 return cursor->next(); \
424const char* ILMatcher::MatchOpCodeToCString(
MatchOpCode opcode) {
426 return "kMatchAndMoveBranchTrue";
429 return "kMatchAndMoveBranchFalse";
431 if (opcode ==
kNop) {
438 return "kMoveParallelMoves";
444 return "kMoveDebugStepChecks";
448#define EMIT_CASE(Instruction, _) \
449 case kMatch##Instruction: \
450 return "kMatch" #Instruction; \
451 case kMatchAndMove##Instruction: \
452 return "kMatchAndMove" #Instruction; \
453 case kMatchAndMoveOptional##Instruction: \
454 return "kMatchAndMoveOptional" #Instruction;
static float next(float f)
static Dart_Handle NewHandle(Thread *thread, ObjectPtr raw)
static ObjectPtr UnwrapHandle(Dart_Handle object)
static void AssignEdgeWeights(FlowGraph *flow_graph)
TypeParameterPtr TypeParameterAt(intptr_t index, Nullability nullability=Nullability::kNonNullable) const
static CodePtr FinalizeCode(FlowGraphCompiler *compiler, compiler::Assembler *assembler, PoolAttachment pool_attachment, bool optimized, CodeStatistics *stats)
static CompilationPipeline * New(Zone *zone, const Function &function)
static DART_WARN_UNUSED_RESULT FlowGraph * RunPipeline(PipelineMode mode, CompilerPassState *state, bool compute_ssa=true)
static DART_WARN_UNUSED_RESULT FlowGraph * RunPipelineWithPasses(CompilerPassState *state, std::initializer_list< CompilerPass::Id > passes)
static constexpr intptr_t kNoOSRDeoptId
static void DisassembleCode(const Function &function, const Code &code, bool optimized)
void FinalizeVarDescriptors(const Code &code)
void FinalizeCatchEntryMovesMap(const Code &code)
void FinalizeStaticCallTargetsTable(const Code &code)
void FinalizeExceptionHandlers(const Code &code)
void FinalizeStackMaps(const Code &code)
void FinalizeCodeSourceMap(const Code &code)
ArrayPtr CreateDeoptInfo(compiler::Assembler *assembler)
void FinalizePcDescriptors(const Code &code)
static void PrintGraph(const char *phase, FlowGraph *flow_graph)
void PopulateWithICData(const Function &function)
bool should_reorder_blocks() const
void set_unoptimized_code(const Code &value) const
void RestoreICDataMap(ZoneGrowableArray< const ICData * > *deopt_id_to_ic_data, bool clone_ic_data) const
void InstallOptimizedCode(const Code &code) const
void AttachCode(const Code &value) const
TypeParameterPtr TypeParameterAt(intptr_t index, Nullability nullability=Nullability::kNonNullable) const
bool TryMatch(std::initializer_list< MatchCode > match_codes, MatchOpCode insert_before=kInvalidMatchOpCode)
Instruction * next() const
const char * ToCString() const
SafepointRwLock * program_lock()
ClassPtr LookupClassAllowPrivate(const String &name) const
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static Object & ZoneHandle()
static StringPtr New(Thread *thread, const char *cstr)
static Dart_Handle LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri=RESOLVED_USER_TEST_URI, bool finalize=true, bool allow_compile_errors=false)
static Dart_Handle ReloadTestScript(const char *script)
void RunAdditionalPasses(std::initializer_list< CompilerPass::Id > passes)
FlowGraph * RunPasses(std::initializer_list< CompilerPass::Id > passes)
void CompileGraphAndAttachFunction()
void RunForcedOptimizedAfterSSAPasses()
static Thread * Current()
IsolateGroup * isolate_group() const
struct _Dart_Handle * Dart_Handle
Dart_NativeFunction(* Dart_NativeEntryResolver)(Dart_Handle name, int num_of_arguments, bool *auto_setup_scope)
Dart_NativeFunction function
#define FOR_EACH_INSTRUCTION(M)
#define FOR_EACH_ABSTRACT_INSTRUCTION(M)
#define EMIT_CASE(Instruction, _)
LibraryPtr LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri)
@ kMatchAndMoveBranchFalse
@ kMatchAndMoveBranchTrue
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
ObjectPtr Invoke(const Library &lib, const char *name)
FunctionPtr GetFunction(const Library &lib, const char *name)
LibraryPtr ReloadTestScript(const char *script)
ClassPtr GetClass(const Library &lib, const char *name)
Dart_Handle NewString(const char *str)
TypeParameterPtr GetClassTypeParameter(const Class &klass, intptr_t index)
TypeParameterPtr GetFunctionTypeParameter(const Function &fun, intptr_t index)
InstructionsPtr BuildInstructions(std::function< void(compiler::Assembler *assembler)> fun)
CallSpecializer * call_specializer
GrowableArray< TokenPosition > inline_id_to_token_pos
GrowableArray< intptr_t > caller_inline_id
GrowableArray< const Function * > inline_id_to_function
#define EXPECT_VALID(handle)