Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
il_printer.cc
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
6
7#include <tuple>
8
9#include "vm/class_id.h"
15#include "vm/os.h"
16#include "vm/parser.h"
17
18namespace dart {
19
20#if defined(INCLUDE_IL_PRINTER)
21DEFINE_FLAG(bool,
22 display_sorted_ic_data,
23 false,
24 "Calls display a unary, sorted-by count form of ICData");
25DEFINE_FLAG(bool, print_environments, false, "Print SSA environments.");
26DEFINE_FLAG(bool,
27 print_flow_graph_as_json,
28 false,
29 "Use machine readable output when printing IL graphs.");
30DEFINE_FLAG(bool, print_redundant_il, false, "Print redundant IL instructions");
31
32DECLARE_FLAG(bool, trace_inlining_intervals);
33
34static bool IsRedundant(Instruction* instr) {
35 if (auto constant = instr->AsConstant()) {
36 return !constant->HasUses();
37 } else if (auto move = instr->AsParallelMove()) {
38 return move->IsRedundant();
39 } else {
40 return false;
41 }
42}
43
44static bool ShouldPrintInstruction(Instruction* instr) {
45 return FLAG_print_redundant_il || !IsRedundant(instr);
46}
47
48class IlTestPrinter : public AllStatic {
49 public:
50 static void PrintGraph(const char* phase, FlowGraph* flow_graph) {
51 JSONWriter writer;
52 writer.OpenObject();
53 writer.PrintProperty("p", phase);
54 writer.PrintProperty("f", flow_graph->function().ToFullyQualifiedCString());
55 writer.OpenArray("b");
56 for (auto block : flow_graph->reverse_postorder()) {
57 PrintBlock(&writer, block);
58 }
59 writer.CloseArray();
60 const auto& codegen_order = *flow_graph->CodegenBlockOrder();
61 if (!codegen_order.is_empty() &&
62 (&codegen_order != &flow_graph->reverse_postorder())) {
63 writer.OpenArray("cbo");
64 const auto block_count = flow_graph->reverse_postorder().length();
65 for (auto block : codegen_order) {
66 writer.PrintValue64((block_count - 1) - block->postorder_number());
67 }
68 writer.CloseArray();
69 }
70 writer.OpenObject("desc");
71 AttributesSerializer(&writer).WriteDescriptors();
72 writer.CloseObject();
73 writer.OpenObject("flags");
74 writer.PrintPropertyBool("nnbd", true);
75 writer.CloseObject();
76 writer.CloseObject();
77 THR_Print("%s\n", writer.ToCString());
78 }
79
80 static void PrintBlock(JSONWriter* writer, BlockEntryInstr* block) {
81 writer->OpenObject();
82 writer->PrintProperty64("b", block->block_id());
83 writer->PrintProperty("o", block->DebugName());
84 if (auto block_with_defs = block->AsBlockEntryWithInitialDefs()) {
85 if (block_with_defs->initial_definitions() != nullptr &&
86 block_with_defs->initial_definitions()->length() > 0) {
87 writer->OpenArray("d");
88 for (auto defn : *block_with_defs->initial_definitions()) {
89 if (ShouldPrintInstruction(defn)) {
90 PrintInstruction(writer, defn);
91 }
92 }
93 writer->CloseArray();
94 }
95 }
96 writer->OpenArray("is");
97 if (auto join = block->AsJoinEntry()) {
98 for (PhiIterator it(join); !it.Done(); it.Advance()) {
99 if (ShouldPrintInstruction(it.Current())) {
100 PrintInstruction(writer, it.Current());
101 }
102 }
103 }
104 for (auto instr : block->instructions()) {
105 if (instr->ArgumentCount() != 0 && instr->GetMoveArguments() != nullptr) {
106 for (auto move_arg : *(instr->GetMoveArguments())) {
107 PrintInstruction(writer, move_arg);
108 }
109 }
110 if (ShouldPrintInstruction(instr) && !instr->IsMoveArgument()) {
111 PrintInstruction(writer, instr);
112 }
113 }
114 writer->CloseArray();
115 writer->CloseObject();
116 }
117
118 static void PrintInstruction(JSONWriter* writer,
119 Instruction* instr,
120 const char* name = nullptr) {
121 writer->OpenObject(name);
122 if (auto defn = instr->AsDefinition()) {
123 if (defn->ssa_temp_index() != -1) {
124 writer->PrintProperty("v", defn->ssa_temp_index());
125 }
126
127 if (defn->HasType()) {
128 writer->OpenObject("T");
129 defn->Type()->PrintTo(writer);
130 writer->CloseObject();
131 }
132 }
133 writer->PrintProperty("o", instr->DebugName());
134 if (auto branch = instr->AsBranch()) {
135 PrintInstruction(writer, branch->comparison(), "cc");
136 } else {
137 if (instr->InputCount() != 0) {
138 writer->OpenArray("i");
139 for (intptr_t i = 0; i < instr->InputCount(); i++) {
140 writer->PrintValue(instr->InputAt(i)->definition()->ssa_temp_index());
141 }
142 writer->CloseArray();
143 } else if (instr->ArgumentCount() != 0 &&
144 instr->GetMoveArguments() != nullptr) {
145 writer->OpenArray("i");
146 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) {
147 writer->PrintValue(
148 instr->ArgumentValueAt(i)->definition()->ssa_temp_index());
149 }
150 writer->CloseArray();
151 }
152 AttributesSerializer serializer(writer);
153 instr->Accept(&serializer);
154 }
155 if (instr->SuccessorCount() > 0) {
156 writer->OpenArray("s");
157 for (auto succ : instr->successors()) {
158 writer->PrintValue(succ->block_id());
159 }
160 writer->CloseArray();
161 }
162 writer->CloseObject();
163 }
164
165 template <typename T>
166 class HasGetAttributes {
167 template <typename U>
168 static std::true_type test(decltype(&U::GetAttributes));
169 template <typename U>
170 static std::false_type test(...);
171
172 public:
173 static constexpr bool value = decltype(test<T>(nullptr))::value;
174 };
175
176 class AttributesSerializer : public InstructionVisitor {
177 public:
178 explicit AttributesSerializer(JSONWriter* writer) : writer_(writer) {}
179
180 void WriteDescriptors() {
181#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
182 WriteDescriptor<ShortName##Instr>(#ShortName);
183
185
186#undef DECLARE_VISIT_INSTRUCTION
187 }
188
189#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
190 virtual void Visit##ShortName(ShortName##Instr* instr) { Write(instr); }
191
193
194#undef DECLARE_VISIT_INSTRUCTION
195
196 private:
197 void WriteAttribute(const char* value) { writer_->PrintValue(value); }
198
199 void WriteAttribute(intptr_t value) { writer_->PrintValue(value); }
200
201 void WriteAttribute(bool value) { writer_->PrintValueBool(value); }
202
203 void WriteAttribute(Token::Kind kind) {
204 writer_->PrintValue(Token::Str(kind));
205 }
206
207 void WriteAttribute(Representation rep) {
208 writer_->PrintValue(RepresentationUtils::ToCString(rep));
209 }
210
211 static const char* LocationKindAsString(const Location& loc) {
212 if (loc.IsConstant()) {
213 return "C";
214 } else if (loc.IsPairLocation()) {
215 auto pair = loc.AsPairLocation();
216 return Thread::Current()->zone()->PrintToString(
217 "(%s, %s)", LocationKindAsString(pair->At(0)),
218 LocationKindAsString(pair->At(0)));
219 } else {
220 switch (loc.kind()) {
221 case Location::kUnallocated:
222 return ".";
223 case Location::kStackSlot:
224 return "stack(word)";
225 case Location::kDoubleStackSlot:
226 return "stack(f64)";
227 case Location::kQuadStackSlot:
228 return "stack(f128)";
229 case Location::kRegister:
230 return "reg(cpu)";
231 case Location::kFpuRegister:
232 return "reg(fpu)";
233 default:
234 return "?";
235 }
236 }
237 }
238
239 void WriteAttribute(const Location& loc) {
240 writer_->PrintValue(LocationKindAsString(loc));
241 }
242
243 void WriteAttribute(const Slot* slot) { writer_->PrintValue(slot->Name()); }
244
245 void WriteAttribute(const Function* function) {
246 writer_->PrintValue(function->QualifiedUserVisibleNameCString());
247 }
248
249 void WriteAttribute(const Object* obj) {
250 if (obj->IsNull()) {
251 writer_->PrintValueNull();
252 } else if (obj->IsBool()) {
253 writer_->PrintValueBool(Bool::Cast(*obj).value());
254 } else if (obj->IsInteger()) {
255 auto value = Integer::Cast(*obj).AsInt64Value();
256 // PrintValue64 and PrintValue will check if integer is representable
257 // as a JS number, which is too strict. We don't actually need
258 // such checks because we only load resulting JSON in Dart.
259 writer_->buffer()->Printf("%" Pd64 "", value);
260 } else if (obj->IsString()) {
261 const auto& str = String::Cast(*obj);
262 writer_->PrintValueStr(str, 0, str.Length());
263 } else {
264 const auto& cls = Class::Handle(obj->clazz());
265 writer_->PrintfValue("Instance of %s", cls.UserVisibleNameCString());
266 }
267 }
268
269 template <typename... Ts>
270 void WriteTuple(const std::tuple<Ts...>& tuple) {
271 std::apply(
272 [&](Ts const&... elements) { (WriteAttribute(elements), ...); },
273 tuple);
274 }
275
276 template <typename T,
277 typename = typename std::enable_if_t<HasGetAttributes<T>::value>>
278 void Write(T* instr) {
279 writer_->OpenArray("d");
280 WriteTuple(instr->GetAttributes());
281 writer_->CloseArray();
282 }
283
284 void Write(Instruction* instr) {
285 // Default, do nothing.
286 }
287
288 void WriteAttributeName(const char* str) {
289 ASSERT(str != nullptr);
290 // To simplify the declaring side, we assume the string might be directly
291 // stringized from one of the following expression forms:
292 //
293 // * &name()
294 // * name()
295 // * name_
296 //
297 // Remove the non-name parts of the above before printing.
298 const intptr_t start = str[0] == '&' ? 1 : 0;
299 intptr_t end = strlen(str);
300 switch (str[end - 1]) {
301 case ')':
302 ASSERT(end >= 2);
303 ASSERT_EQUAL(str[end - 2], '(');
304 end -= 2;
305 break;
306 case '_':
307 // Strip off the final _ from a direct private field access.
308 end -= 1;
309 break;
310 default:
311 break;
312 }
313 writer_->PrintValue(str + start, end - start);
314 }
315
316 template <typename... Ts>
317 void WriteAttributeNames(const std::tuple<Ts...>& tuple) {
318 std::apply(
319 [&](Ts const&... elements) { (WriteAttributeName(elements), ...); },
320 tuple);
321 }
322
323 template <typename T>
324 void WriteDescriptor(
325 const char* name,
326 typename std::enable_if_t<HasGetAttributes<T>::value>* = nullptr) {
327 writer_->OpenArray(name);
328 WriteAttributeNames(T::GetAttributeNames());
329 writer_->CloseArray();
330 }
331
332 template <typename T>
333 void WriteDescriptor(
334 const char* name,
335 typename std::enable_if_t<!HasGetAttributes<T>::value>* = nullptr) {}
336
337 JSONWriter* writer_;
338 };
339};
340
342 const Function& function,
343 uint8_t** compiler_pass_filter /* = nullptr */) {
344 return compiler::PrintFilter::ShouldPrint(function, compiler_pass_filter);
345}
346
347void FlowGraphPrinter::PrintGraph(const char* phase, FlowGraph* flow_graph) {
348 LogBlock lb;
349 if (FLAG_print_flow_graph_as_json) {
350 IlTestPrinter::PrintGraph(phase, flow_graph);
351 } else {
352 THR_Print("*** BEGIN CFG\n%s\n", phase);
353 FlowGraphPrinter printer(*flow_graph);
354 printer.PrintBlocks();
355 THR_Print("*** END CFG\n");
356 }
357 fflush(stdout);
358}
359
360void FlowGraphPrinter::PrintBlock(BlockEntryInstr* block,
361 bool print_locations) {
362 // Print the block entry.
363 PrintOneInstruction(block, print_locations);
364 THR_Print("\n");
365 // And all the successors in the block.
366 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
367 Instruction* current = it.Current();
368
369 // Skip redundant parallel moves.
370 if (!ShouldPrintInstruction(current)) {
371 continue;
372 }
373
374 PrintOneInstruction(current, print_locations);
375 THR_Print("\n");
376 }
377}
378
380 if (!function_.IsNull()) {
381 THR_Print("==== %s (%s", function_.ToFullyQualifiedCString(),
382 Function::KindToCString(function_.kind()));
383 // Output saved arguments descriptor information for dispatchers that
384 // have it, so it's easy to see which dispatcher this graph represents.
385 if (function_.HasSavedArgumentsDescriptor()) {
386 const auto& args_desc_array = Array::Handle(function_.saved_args_desc());
387 const ArgumentsDescriptor args_desc(args_desc_array);
388 THR_Print(", %s", args_desc.ToCString());
389 }
390 THR_Print(")\n");
391 }
392
393 for (intptr_t i = 0; i < block_order_.length(); ++i) {
394 PrintBlock(block_order_[i], print_locations_);
395 }
396}
397
398void FlowGraphPrinter::PrintInstruction(Instruction* instr) {
399 PrintOneInstruction(instr, print_locations_);
400}
401
402void FlowGraphPrinter::PrintOneInstruction(Instruction* instr,
403 bool print_locations) {
404 char str[4000];
405 BufferFormatter f(str, sizeof(str));
406 instr->PrintTo(&f);
407 if (FLAG_print_environments && (instr->env() != nullptr)) {
408 instr->env()->PrintTo(&f);
409 }
410 if (print_locations && (instr->HasLocs())) {
411 instr->locs()->PrintTo(&f);
412 }
415 }
416 if (!instr->IsBlockEntry()) THR_Print(" ");
417 THR_Print("%s", str);
418 if (FLAG_trace_inlining_intervals) {
419 THR_Print(" iid: %" Pd "", instr->inlining_id());
420 }
421}
422
423void FlowGraphPrinter::PrintTypeCheck(const ParsedFunction& parsed_function,
424 TokenPosition token_pos,
425 Value* value,
426 const AbstractType& dst_type,
427 const String& dst_name,
428 bool eliminated) {
429 const char* compile_type_name = "unknown";
430 if (value != nullptr && value->reaching_type_ != nullptr) {
431 compile_type_name = value->reaching_type_->ToCString();
432 }
433 THR_Print(
434 "%s type check: compile type %s is %s specific than "
435 "type '%s' of '%s'.\n",
436 eliminated ? "Eliminated" : "Generated", compile_type_name,
437 eliminated ? "more" : "not more", dst_type.NameCString(),
438 dst_name.ToCString());
439}
440
441static void PrintTargetsHelper(BaseTextBuffer* f,
442 const CallTargets& targets,
443 intptr_t num_checks_to_print) {
444 f->AddString(" Targets[");
445 f->Printf("%" Pd ": ", targets.length());
446 Function& target = Function::Handle();
447 if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
448 (num_checks_to_print > targets.length())) {
449 num_checks_to_print = targets.length();
450 }
451 for (intptr_t i = 0; i < num_checks_to_print; i++) {
452 const CidRange& range = targets[i];
453 const auto target_info = targets.TargetAt(i);
454 const intptr_t count = target_info->count;
455 target = target_info->target->ptr();
456 if (i > 0) {
457 f->AddString(" | ");
458 }
459 if (range.IsSingleCid()) {
460 const Class& cls = Class::Handle(
461 IsolateGroup::Current()->class_table()->At(range.cid_start));
462 f->Printf("%s", String::Handle(cls.Name()).ToCString());
463 f->Printf(" cid %" Pd " cnt:%" Pd " trgt:'%s'", range.cid_start, count,
464 target.ToQualifiedCString());
465 } else {
466 const Class& cls = Class::Handle(target.Owner());
467 f->Printf("cid %" Pd "-%" Pd " %s", range.cid_start, range.cid_end,
468 String::Handle(cls.Name()).ToCString());
469 f->Printf(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString());
470 }
471
472 if (target_info->exactness.IsTracking()) {
473 f->Printf(" %s", target_info->exactness.ToCString());
474 }
475 }
476 if (num_checks_to_print < targets.length()) {
477 f->AddString("...");
478 }
479 f->AddString("]");
480}
481
482static void PrintCidsHelper(BaseTextBuffer* f,
483 const Cids& targets,
484 intptr_t num_checks_to_print) {
485 f->AddString(" Cids[");
486 f->Printf("%" Pd ": ", targets.length());
487 if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
488 (num_checks_to_print > targets.length())) {
489 num_checks_to_print = targets.length();
490 }
491 for (intptr_t i = 0; i < num_checks_to_print; i++) {
492 const CidRange& range = targets[i];
493 if (i > 0) {
494 f->AddString(" | ");
495 }
496 const Class& cls = Class::Handle(
497 IsolateGroup::Current()->class_table()->At(range.cid_start));
498 f->Printf("%s etc. ", String::Handle(cls.Name()).ToCString());
499 if (range.IsSingleCid()) {
500 f->Printf(" cid %" Pd, range.cid_start);
501 } else {
502 f->Printf(" cid %" Pd "-%" Pd, range.cid_start, range.cid_end);
503 }
504 }
505 if (num_checks_to_print < targets.length()) {
506 f->AddString("...");
507 }
508 f->AddString("]");
509}
510
511static void PrintICDataHelper(BaseTextBuffer* f,
512 const ICData& ic_data,
513 intptr_t num_checks_to_print) {
514 f->AddString(" IC[");
515 if (ic_data.is_tracking_exactness()) {
516 f->Printf(
517 "(%s) ",
518 AbstractType::Handle(ic_data.receivers_static_type()).ToCString());
519 }
520 f->Printf("%" Pd ": ", ic_data.NumberOfChecks());
521 Function& target = Function::Handle();
522 if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
523 (num_checks_to_print > ic_data.NumberOfChecks())) {
524 num_checks_to_print = ic_data.NumberOfChecks();
525 }
526 for (intptr_t i = 0; i < num_checks_to_print; i++) {
527 GrowableArray<intptr_t> class_ids;
528 ic_data.GetCheckAt(i, &class_ids, &target);
529 const intptr_t count = ic_data.GetCountAt(i);
530 if (i > 0) {
531 f->AddString(" | ");
532 }
533 for (intptr_t k = 0; k < class_ids.length(); k++) {
534 if (k > 0) {
535 f->AddString(", ");
536 }
537 const Class& cls = Class::Handle(
538 IsolateGroup::Current()->class_table()->At(class_ids[k]));
539 f->Printf("%s", String::Handle(cls.Name()).ToCString());
540 }
541 f->Printf(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString());
542 if (ic_data.is_tracking_exactness()) {
543 f->Printf(" %s", ic_data.GetExactnessAt(i).ToCString());
544 }
545 }
546 if (num_checks_to_print < ic_data.NumberOfChecks()) {
547 f->AddString("...");
548 }
549 f->AddString("]");
550}
551
552static void PrintICDataSortedHelper(BaseTextBuffer* f,
553 const ICData& ic_data_orig) {
554 const ICData& ic_data =
555 ICData::Handle(ic_data_orig.AsUnaryClassChecksSortedByCount());
556 f->Printf(" IC[n:%" Pd "; ", ic_data.NumberOfChecks());
557 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
558 const intptr_t count = ic_data.GetCountAt(i);
559 const intptr_t cid = ic_data.GetReceiverClassIdAt(i);
560 const Class& cls =
561 Class::Handle(IsolateGroup::Current()->class_table()->At(cid));
562 f->Printf("%s : %" Pd ", ", String::Handle(cls.Name()).ToCString(), count);
563 }
564 f->AddString("]");
565}
566
567void FlowGraphPrinter::PrintICData(const ICData& ic_data,
568 intptr_t num_checks_to_print) {
569 char buffer[1024];
570 BufferFormatter f(buffer, sizeof(buffer));
571 PrintICDataHelper(&f, ic_data, num_checks_to_print);
572 THR_Print("%s ", buffer);
573 const Array& a = Array::Handle(ic_data.arguments_descriptor());
574 THR_Print(" arg-desc %" Pd "\n", a.Length());
575}
576
577void FlowGraphPrinter::PrintCidRangeData(const CallTargets& targets,
578 intptr_t num_checks_to_print) {
579 char buffer[1024];
580 BufferFormatter f(buffer, sizeof(buffer));
581 PrintTargetsHelper(&f, targets, num_checks_to_print);
582 THR_Print("%s ", buffer);
583 // TODO(erikcorry): Print args descriptor.
584}
585
586static void PrintUse(BaseTextBuffer* f, const Definition& definition) {
587 if (definition.HasSSATemp()) {
588 f->Printf("v%" Pd "", definition.ssa_temp_index());
589 } else if (definition.HasTemp()) {
590 f->Printf("t%" Pd "", definition.temp_index());
591 }
592}
593
594const char* Instruction::ToCString() const {
595 char buffer[1024];
596 BufferFormatter f(buffer, sizeof(buffer));
597 PrintTo(&f);
599}
600
601void Instruction::PrintTo(BaseTextBuffer* f) const {
602 if (GetDeoptId() != DeoptId::kNone) {
603 f->Printf("%s:%" Pd "(", DebugName(), GetDeoptId());
604 } else {
605 f->Printf("%s(", DebugName());
606 }
607 PrintOperandsTo(f);
608 f->AddString(")");
609}
610
611void Instruction::PrintOperandsTo(BaseTextBuffer* f) const {
612 for (int i = 0; i < InputCount(); ++i) {
613 if (i > 0) f->AddString(", ");
614 if (InputAt(i) != nullptr) InputAt(i)->PrintTo(f);
615 }
616}
617
618void Definition::PrintTo(BaseTextBuffer* f) const {
619 PrintUse(f, *this);
620 if (HasSSATemp() || HasTemp()) f->AddString(" <- ");
621 if (GetDeoptId() != DeoptId::kNone) {
622 f->Printf("%s:%" Pd "(", DebugName(), GetDeoptId());
623 } else {
624 f->Printf("%s(", DebugName());
625 }
626 PrintOperandsTo(f);
627 f->AddString(")");
628 if (range_ != nullptr) {
629 f->AddString(" ");
630 range_->PrintTo(f);
631 }
632
633 if (representation() != kNoRepresentation && representation() != kTagged) {
635 } else if (type_ != nullptr) {
636 f->AddString(" ");
637 type_->PrintTo(f);
638 }
639}
640
641void CheckNullInstr::PrintOperandsTo(BaseTextBuffer* f) const {
642 Definition::PrintOperandsTo(f);
643 switch (exception_type()) {
644 case kNoSuchMethod:
645 f->AddString(", NoSuchMethodError");
646 break;
647 case kArgumentError:
648 f->AddString(", ArgumentError");
649 break;
650 case kCastError:
651 f->AddString(", CastError");
652 break;
653 }
654}
655
656void Definition::PrintOperandsTo(BaseTextBuffer* f) const {
657 for (int i = 0; i < InputCount(); ++i) {
658 if (i > 0) f->AddString(", ");
659 if (InputAt(i) != nullptr) {
660 InputAt(i)->PrintTo(f);
661 }
662 }
663}
664
665void RedefinitionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
666 Definition::PrintOperandsTo(f);
667 if (constrained_type_ != nullptr) {
668 f->Printf(" ^ %s", constrained_type_->ToCString());
669 }
670}
671
672void ReachabilityFenceInstr::PrintOperandsTo(BaseTextBuffer* f) const {
673 value()->PrintTo(f);
674}
675
676const char* Value::ToCString() const {
677 char buffer[1024];
678 BufferFormatter f(buffer, sizeof(buffer));
679 PrintTo(&f);
681}
682
683void Value::PrintTo(BaseTextBuffer* f) const {
684 PrintUse(f, *definition());
685
686 if ((reaching_type_ != nullptr) && (reaching_type_ != definition()->type_)) {
687 f->AddString(" ");
688 reaching_type_->PrintTo(f);
689 }
690}
691
692void ConstantInstr::PrintOperandsTo(BaseTextBuffer* f) const {
693 const char* cstr = value().ToCString();
694 const char* new_line = strchr(cstr, '\n');
695 if (new_line == nullptr) {
696 f->Printf("#%s", cstr);
697 } else {
698 const intptr_t pos = new_line - cstr;
699 char* buffer = Thread::Current()->zone()->Alloc<char>(pos + 1);
700 strncpy(buffer, cstr, pos);
701 buffer[pos] = '\0';
702 f->Printf("#%s\\n...", buffer);
703 }
704}
705
706void ConstraintInstr::PrintOperandsTo(BaseTextBuffer* f) const {
707 value()->PrintTo(f);
708 f->AddString(" ^ ");
709 constraint()->PrintTo(f);
710}
711
712void Range::PrintTo(BaseTextBuffer* f) const {
713 f->AddString("[");
714 min_.PrintTo(f);
715 f->AddString(", ");
716 max_.PrintTo(f);
717 f->AddString("]");
718}
719
720const char* Range::ToCString(const Range* range) {
721 if (range == nullptr) return "[_|_, _|_]";
722
723 char buffer[256];
724 BufferFormatter f(buffer, sizeof(buffer));
725 range->PrintTo(&f);
727}
728
729void RangeBoundary::PrintTo(BaseTextBuffer* f) const {
730 switch (kind_) {
731 case kSymbol:
732 f->Printf("v%" Pd "",
733 reinterpret_cast<Definition*>(value_)->ssa_temp_index());
734 if (offset_ != 0) f->Printf("%+" Pd64 "", offset_);
735 break;
736 case kConstant:
737 f->Printf("%" Pd64 "", value_);
738 break;
739 case kUnknown:
740 f->AddString("_|_");
741 break;
742 }
743}
744
745const char* RangeBoundary::ToCString() const {
746 char buffer[256];
747 BufferFormatter f(buffer, sizeof(buffer));
748 PrintTo(&f);
750}
751
752void MakeTempInstr::PrintOperandsTo(BaseTextBuffer* f) const {}
753
754void DropTempsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
755 f->Printf("%" Pd "", num_temps());
756 if (value() != nullptr) {
757 f->AddString(", ");
758 value()->PrintTo(f);
759 }
760}
761
762void AssertAssignableInstr::PrintOperandsTo(BaseTextBuffer* f) const {
763 value()->PrintTo(f);
764 f->AddString(", ");
765 dst_type()->PrintTo(f);
766 f->Printf(", '%s',", dst_name().ToCString());
767 f->AddString(" instantiator_type_args(");
768 instantiator_type_arguments()->PrintTo(f);
769 f->AddString("), function_type_args(");
770 function_type_arguments()->PrintTo(f);
771 f->AddString(")");
772}
773
774void AssertSubtypeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
775 sub_type()->PrintTo(f);
776 f->AddString(", ");
777 super_type()->PrintTo(f);
778 f->AddString(", ");
779 dst_name()->PrintTo(f);
780 f->AddString(", instantiator_type_args(");
781 instantiator_type_arguments()->PrintTo(f);
782 f->AddString("), function_type_args(");
783 function_type_arguments()->PrintTo(f);
784 f->AddString(")");
785}
786
787void AssertBooleanInstr::PrintOperandsTo(BaseTextBuffer* f) const {
788 value()->PrintTo(f);
789}
790
791void ClosureCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
792 if (FLAG_precompiled_mode) {
793 f->AddString(" closure=");
794 } else {
795 f->AddString(" function=");
796 }
797 InputAt(InputCount() - 1)->PrintTo(f);
798 f->Printf("<%" Pd ">", type_args_len());
799 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
800 f->AddString(", ");
801 ArgumentValueAt(i)->PrintTo(f);
802 }
803}
804
805void InstanceCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
806 f->Printf(" %s<%" Pd ">", function_name().ToCString(), type_args_len());
807 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
808 f->AddString(", ");
809 ArgumentValueAt(i)->PrintTo(f);
810 }
811 if (HasICData()) {
812 if (FLAG_display_sorted_ic_data) {
813 PrintICDataSortedHelper(f, *ic_data());
814 } else {
815 PrintICDataHelper(f, *ic_data(), FlowGraphPrinter::kPrintAll);
816 }
817 }
818 if (result_type() != nullptr) {
819 f->Printf(", result_type = %s", result_type()->ToCString());
820 }
821 if (entry_kind() == Code::EntryKind::kUnchecked) {
822 f->AddString(" using unchecked entrypoint");
823 }
824}
825
826void PolymorphicInstanceCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
827 f->Printf(" %s<%" Pd ">", function_name().ToCString(), type_args_len());
828 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
829 f->AddString(", ");
830 ArgumentValueAt(i)->PrintTo(f);
831 }
832 PrintTargetsHelper(f, targets_, FlowGraphPrinter::kPrintAll);
833 if (complete()) {
834 f->AddString(" COMPLETE");
835 }
836 if (entry_kind() == Code::EntryKind::kUnchecked) {
837 f->AddString(" using unchecked entrypoint");
838 }
839}
840
841void DispatchTableCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
842 const String& name =
843 String::Handle(interface_target().QualifiedUserVisibleName());
844 f->AddString(" cid=");
845 class_id()->PrintTo(f);
846 f->Printf(" %s<%" Pd ">", name.ToCString(), type_args_len());
847 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
848 f->AddString(", ");
849 ArgumentValueAt(i)->PrintTo(f);
850 }
851}
852
853void StrictCompareInstr::PrintOperandsTo(BaseTextBuffer* f) const {
854 f->Printf("%s, ", Token::Str(kind()));
855 left()->PrintTo(f);
856 f->AddString(", ");
857 right()->PrintTo(f);
858 if (needs_number_check()) {
859 f->Printf(", with number check");
860 }
861}
862
863void TestCidsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
864 left()->PrintTo(f);
865 f->Printf(" %s [", Token::Str(kind()));
866 intptr_t length = cid_results().length();
867 for (intptr_t i = 0; i < length; i += 2) {
868 f->Printf("0x%" Px ":%s ", cid_results()[i],
869 cid_results()[i + 1] == 0 ? "false" : "true");
870 }
871 f->AddString("] ");
872 if (CanDeoptimize()) {
873 ASSERT(deopt_id() != DeoptId::kNone);
874 f->AddString("else deoptimize ");
875 } else {
876 ASSERT(deopt_id() == DeoptId::kNone);
877 f->Printf("else %s ", cid_results()[length - 1] != 0 ? "false" : "true");
878 }
879}
880
881void TestRangeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
882 left()->PrintTo(f);
883 f->Printf(" %s [%" Pd "-%" Pd "]", kind() == Token::kIS ? "in" : "not in",
884 lower_, upper_);
885}
886
887void EqualityCompareInstr::PrintOperandsTo(BaseTextBuffer* f) const {
888 left()->PrintTo(f);
889 f->Printf(" %s ", Token::Str(kind()));
890 right()->PrintTo(f);
891}
892
893void StaticCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
894 f->Printf(" %s<%" Pd "> ", String::Handle(function().name()).ToCString(),
895 type_args_len());
896 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
897 if (i > 0) f->AddString(", ");
898 ArgumentValueAt(i)->PrintTo(f);
899 }
900 if (entry_kind() == Code::EntryKind::kUnchecked) {
901 f->AddString(", using unchecked entrypoint");
902 }
903 if (function().recognized_kind() != MethodRecognizer::kUnknown) {
904 f->Printf(", recognized_kind = %s",
905 MethodRecognizer::KindToCString(function().recognized_kind()));
906 }
907 if (result_type() != nullptr) {
908 f->Printf(", result_type = %s", result_type()->ToCString());
909 }
910}
911
912void CachableIdempotentCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
913 f->Printf(" %s<%" Pd "> ", String::Handle(function().name()).ToCString(),
914 type_args_len());
915 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
916 if (i > 0) f->AddString(", ");
917 ArgumentValueAt(i)->PrintTo(f);
918 }
919}
920
921void LoadLocalInstr::PrintOperandsTo(BaseTextBuffer* f) const {
922 f->Printf("%s @%d", local().name().ToCString(), local().index().value());
923}
924
925void StoreLocalInstr::PrintOperandsTo(BaseTextBuffer* f) const {
926 f->Printf("%s @%d, ", local().name().ToCString(), local().index().value());
927 value()->PrintTo(f);
928}
929
930void NativeCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
931 f->Printf("%s", native_name().ToCString());
932}
933
934void GuardFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
935 f->Printf("%s %s, ", String::Handle(field().name()).ToCString(),
936 field().GuardedPropertiesAsCString());
937 value()->PrintTo(f);
938}
939
940void StoreFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
941 instance()->PrintTo(f);
942 f->Printf(" . %s = ", slot().Name());
943 value()->PrintTo(f);
944 if (slot().representation() != kTagged) {
945 f->Printf(" <%s>", RepresentationUtils::ToCString(slot().representation()));
946 }
947
948 // Here, we just print the value of the enum field. We would prefer to get
949 // the final decision on whether a store barrier will be emitted by calling
950 // ShouldEmitStoreBarrier(), but that can change parts of the flow graph.
951 if (emit_store_barrier_ == kNoStoreBarrier) {
952 f->AddString(", NoStoreBarrier");
953 }
955 f->AddString(", MayStoreInnerPointer");
956 }
957}
958
959void IfThenElseInstr::PrintOperandsTo(BaseTextBuffer* f) const {
960 comparison()->PrintOperandsTo(f);
961 f->Printf(" ? %" Pd " : %" Pd, if_true_, if_false_);
962}
963
964void LoadStaticFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
965 f->Printf("%s", String::Handle(field().name()).ToCString());
966 if (calls_initializer()) {
967 f->AddString(", CallsInitializer");
968 }
969}
970
971void StoreStaticFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
972 f->Printf("%s, ", String::Handle(field().name()).ToCString());
973 value()->PrintTo(f);
974}
975
976void InstanceOfInstr::PrintOperandsTo(BaseTextBuffer* f) const {
977 value()->PrintTo(f);
978 f->Printf(" IS %s,", type().NameCString());
979 f->AddString(" instantiator_type_args(");
980 instantiator_type_arguments()->PrintTo(f);
981 f->AddString("), function_type_args(");
982 function_type_arguments()->PrintTo(f);
983 f->AddString(")");
984}
985
986void RelationalOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
987 f->Printf("%s, ", Token::Str(kind()));
988 left()->PrintTo(f);
989 f->AddString(", ");
990 right()->PrintTo(f);
991}
992
993void AllocationInstr::PrintOperandsTo(BaseTextBuffer* f) const {
994 Definition::PrintOperandsTo(f);
995 if (Identity().IsNotAliased()) {
996 if (InputCount() > 0) {
997 f->AddString(", ");
998 }
999 f->AddString("<not-aliased>");
1000 }
1001}
1002
1003void AllocateObjectInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1004 f->Printf("cls=%s", cls().ScrubbedNameCString());
1005 if (InputCount() > 0 || Identity().IsNotAliased()) {
1006 f->AddString(", ");
1007 }
1008 AllocationInstr::PrintOperandsTo(f);
1009}
1010
1011void MaterializeObjectInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1012 f->Printf("%s", cls_.ScrubbedNameCString());
1013 for (intptr_t i = 0; i < InputCount(); i++) {
1014 f->AddString(", ");
1015 f->Printf("%s: ", slots_[i]->Name());
1016 InputAt(i)->PrintTo(f);
1017 }
1018}
1019
1020void LoadFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1021 instance()->PrintTo(f);
1022 f->Printf(" . %s%s", slot().Name(), IsImmutableLoad() ? " {final}" : "");
1023 if (calls_initializer()) {
1024 f->AddString(", CallsInitializer");
1025 }
1027 f->AddString(", MayLoadInnerPointer");
1028 }
1029}
1030
1031void LoadUntaggedInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1032 object()->PrintTo(f);
1033 f->Printf(", %" Pd, offset());
1034}
1035
1036void CalculateElementAddressInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1037 Definition::PrintOperandsTo(f);
1038 f->Printf(", index_scale=%" Pd "", index_scale());
1039}
1040
1041void InstantiateTypeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1042 const String& type_name = String::Handle(type().Name());
1043 f->Printf("%s,", type_name.ToCString());
1044 f->AddString(" instantiator_type_args(");
1045 instantiator_type_arguments()->PrintTo(f);
1046 f->AddString("), function_type_args(");
1047 function_type_arguments()->PrintTo(f);
1048 f->AddString(")");
1049}
1050
1051void InstantiateTypeArgumentsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1052 type_arguments()->PrintTo(f);
1053 f->AddString(", instantiator_type_args(");
1054 instantiator_type_arguments()->PrintTo(f);
1055 f->AddString("), function_type_args(");
1056 function_type_arguments()->PrintTo(f);
1057 f->Printf(")");
1058 if (!instantiator_class().IsNull()) {
1059 f->Printf(", instantiator_class(%s)", instantiator_class().ToCString());
1060 }
1061}
1062
1063void AllocateContextInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1064 f->Printf("num_variables=%" Pd "", num_context_variables());
1065 if (InputCount() > 0 || Identity().IsNotAliased()) {
1066 f->AddString(", ");
1067 }
1068 TemplateAllocation::PrintOperandsTo(f);
1069}
1070
1071void AllocateUninitializedContextInstr::PrintOperandsTo(
1072 BaseTextBuffer* f) const {
1073 f->Printf("num_variables=%" Pd "", num_context_variables());
1074 if (InputCount() > 0 || Identity().IsNotAliased()) {
1075 f->AddString(", ");
1076 }
1077 TemplateAllocation::PrintOperandsTo(f);
1078}
1079
1080void TruncDivModInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1081 Definition::PrintOperandsTo(f);
1082}
1083
1084void ExtractNthOutputInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1085 f->Printf("Extract %" Pd " from ", index());
1086 Definition::PrintOperandsTo(f);
1087}
1088
1089void UnboxLaneInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1090 Definition::PrintOperandsTo(f);
1091 f->Printf(", lane %" Pd, lane());
1092}
1093
1094void BoxLanesInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1095 Definition::PrintOperandsTo(f);
1096}
1097
1098void UnaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1099 f->Printf("%s, ", Token::Str(op_kind()));
1100 value()->PrintTo(f);
1101}
1102
1103void BinaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1104 f->Printf("%s", Token::Str(op_kind()));
1105 if (is_truncating()) {
1106 f->AddString(" [tr]");
1107 } else if (!can_overflow()) {
1108 f->AddString(" [-o]");
1109 }
1110 f->AddString(", ");
1111 left()->PrintTo(f);
1112 f->AddString(", ");
1113 right()->PrintTo(f);
1114}
1115
1116void BinaryDoubleOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1117 f->Printf("%s, ", Token::Str(op_kind()));
1118 left()->PrintTo(f);
1119 f->AddString(", ");
1120 right()->PrintTo(f);
1121}
1122
1123void DoubleTestOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1124 switch (op_kind()) {
1125 case MethodRecognizer::kDouble_getIsNaN:
1126 f->AddString("IsNaN ");
1127 break;
1128 case MethodRecognizer::kDouble_getIsInfinite:
1129 f->AddString("IsInfinite ");
1130 break;
1131 case MethodRecognizer::kDouble_getIsNegative:
1132 f->AddString("IsNegative ");
1133 break;
1134 default:
1135 UNREACHABLE();
1136 }
1137 value()->PrintTo(f);
1138}
1139
1140static const char* const simd_op_kind_string[] = {
1141#define CASE(Arity, Mask, Name, ...) #Name,
1143#undef CASE
1144};
1145
1146void SimdOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1147 f->Printf("%s", simd_op_kind_string[kind()]);
1148 if (HasMask()) {
1149 f->Printf(", mask = %" Pd "", mask());
1150 }
1151 for (intptr_t i = 0; i < InputCount(); i++) {
1152 f->AddString(", ");
1153 InputAt(i)->PrintTo(f);
1154 }
1155}
1156
1157void UnaryDoubleOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1158 f->Printf("%s, ", Token::Str(op_kind()));
1159 value()->PrintTo(f);
1160}
1161
1162void LoadClassIdInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1163 if (!input_can_be_smi_) {
1164 f->AddString("<non-smi> ");
1165 }
1166 object()->PrintTo(f);
1167}
1168
1169void CheckClassIdInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1170 value()->PrintTo(f);
1171
1172 const Class& cls = Class::Handle(
1173 IsolateGroup::Current()->class_table()->At(cids().cid_start));
1174 const String& name = String::Handle(cls.ScrubbedName());
1175 if (cids().IsSingleCid()) {
1176 f->Printf(", %s", name.ToCString());
1177 } else {
1178 const Class& cls2 = Class::Handle(
1179 IsolateGroup::Current()->class_table()->At(cids().cid_end));
1180 const String& name2 = String::Handle(cls2.ScrubbedName());
1181 f->Printf(", cid %" Pd "-%" Pd " %s-%s", cids().cid_start, cids().cid_end,
1182 name.ToCString(), name2.ToCString());
1183 }
1184}
1185
1186void HashIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1187 if (smi_) {
1188 f->AddString("smi ");
1189 }
1190
1191 value()->PrintTo(f);
1192}
1193
1194void CheckClassInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1195 value()->PrintTo(f);
1196 PrintCidsHelper(f, cids_, FlowGraphPrinter::kPrintAll);
1197 if (IsNullCheck()) {
1198 f->AddString(" nullcheck");
1199 }
1200}
1201
1202void CheckConditionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1203 comparison()->PrintOperandsTo(f);
1204}
1205
1206void InvokeMathCFunctionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1207 f->Printf("%s, ", MethodRecognizer::KindToCString(recognized_kind_));
1208 Definition::PrintOperandsTo(f);
1209}
1210
1212 BaseTextBuffer* f) const {
1213 const GrowableArray<Definition*>& defns = initial_definitions_;
1214 if (defns.length() > 0) {
1215 f->AddString(" {");
1216 for (intptr_t i = 0; i < defns.length(); ++i) {
1217 Definition* def = defns[i];
1218 // Skip constants which are not used in the graph.
1219 if (!ShouldPrintInstruction(def)) {
1220 continue;
1221 }
1222 f->AddString("\n ");
1223 def->PrintTo(f);
1224 }
1225 f->AddString("\n}");
1226 }
1227}
1228
1229void GraphEntryInstr::PrintTo(BaseTextBuffer* f) const {
1230 f->Printf("B%" Pd "[graph]:%" Pd, block_id(), GetDeoptId());
1232}
1233
1234void JoinEntryInstr::PrintTo(BaseTextBuffer* f) const {
1235 if (try_index() != kInvalidTryIndex) {
1236 f->Printf("B%" Pd "[join try_idx %" Pd "]:%" Pd " pred(", block_id(),
1237 try_index(), GetDeoptId());
1238 } else {
1239 f->Printf("B%" Pd "[join]:%" Pd " pred(", block_id(), GetDeoptId());
1240 }
1241 for (intptr_t i = 0; i < predecessors_.length(); ++i) {
1242 if (i > 0) f->AddString(", ");
1243 f->Printf("B%" Pd, predecessors_[i]->block_id());
1244 }
1245 f->AddString(")");
1246 if (phis_ != nullptr) {
1247 f->AddString(" {");
1248 for (intptr_t i = 0; i < phis_->length(); ++i) {
1249 if ((*phis_)[i] == nullptr) continue;
1250 f->AddString("\n ");
1251 (*phis_)[i]->PrintTo(f);
1252 }
1253 f->AddString("\n}");
1254 }
1255 if (HasParallelMove()) {
1256 f->AddString(" ");
1257 parallel_move()->PrintTo(f);
1258 }
1259}
1260
1261void IndirectEntryInstr::PrintTo(BaseTextBuffer* f) const {
1262 f->Printf("B%" Pd "[join indirect", block_id());
1263 if (try_index() != kInvalidTryIndex) {
1264 f->Printf(" try_idx %" Pd, try_index());
1265 }
1266 f->Printf("]:%" Pd " pred(", GetDeoptId());
1267 for (intptr_t i = 0; i < predecessors_.length(); ++i) {
1268 if (i > 0) f->AddString(", ");
1269 f->Printf("B%" Pd, predecessors_[i]->block_id());
1270 }
1271 f->AddString(")");
1272 if (phis_ != nullptr) {
1273 f->AddString(" {");
1274 for (intptr_t i = 0; i < phis_->length(); ++i) {
1275 if ((*phis_)[i] == nullptr) continue;
1276 f->AddString("\n ");
1277 (*phis_)[i]->PrintTo(f);
1278 }
1279 f->AddString("\n}");
1280 }
1281 if (HasParallelMove()) {
1282 f->AddString(" ");
1283 parallel_move()->PrintTo(f);
1284 }
1285}
1286
1287void PhiInstr::PrintTo(BaseTextBuffer* f) const {
1288 f->Printf("v%" Pd " <- phi(", ssa_temp_index());
1289 for (intptr_t i = 0; i < inputs_.length(); ++i) {
1290 if (inputs_[i] != nullptr) inputs_[i]->PrintTo(f);
1291 if (i < inputs_.length() - 1) f->AddString(", ");
1292 }
1293 f->AddString(")");
1294 f->AddString(is_alive() ? " alive" : " dead");
1295 if (range_ != nullptr) {
1296 f->AddString(" ");
1297 range_->PrintTo(f);
1298 }
1299
1300 if (representation() != kNoRepresentation && representation() != kTagged) {
1302 }
1303
1304 if (HasType()) {
1305 f->Printf(" %s", TypeAsCString());
1306 }
1307}
1308
1309void UnboxIntegerInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1310 if (is_truncating()) {
1311 f->AddString("[tr], ");
1312 }
1313 if (SpeculativeModeOfInputs() == kGuardInputs) {
1314 f->AddString("[guard-inputs], ");
1315 } else {
1316 f->AddString("[non-speculative], ");
1317 }
1318 Definition::PrintOperandsTo(f);
1319}
1320
1321void IntConverterInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1322 f->Printf("%s->%s%s, ", RepresentationUtils::ToCString(from()),
1324 is_truncating() ? "[tr]" : "");
1325 Definition::PrintOperandsTo(f);
1326}
1327
1328void BitCastInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1329 Definition::PrintOperandsTo(f);
1330 f->Printf(" (%s -> %s)", RepresentationUtils::ToCString(from()),
1332}
1333
1334void ParameterInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1335 f->Printf("%" Pd " @%s", env_index(), location().ToCString());
1336}
1337
1338void CheckStackOverflowInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1339 f->Printf("stack=%" Pd ", loop=%" Pd, stack_depth(), loop_depth());
1340}
1341
1342void TargetEntryInstr::PrintTo(BaseTextBuffer* f) const {
1343 if (try_index() != kInvalidTryIndex) {
1344 f->Printf("B%" Pd "[target try_idx %" Pd "]:%" Pd, block_id(), try_index(),
1345 GetDeoptId());
1346 } else {
1347 f->Printf("B%" Pd "[target]:%" Pd, block_id(), GetDeoptId());
1348 }
1349 if (HasParallelMove()) {
1350 f->AddString(" ");
1351 parallel_move()->PrintTo(f);
1352 }
1353}
1354
1355void OsrEntryInstr::PrintTo(BaseTextBuffer* f) const {
1356 f->Printf("B%" Pd "[osr entry]:%" Pd " stack_depth=%" Pd, block_id(),
1357 GetDeoptId(), stack_depth());
1358 if (HasParallelMove()) {
1359 f->AddString("\n");
1360 parallel_move()->PrintTo(f);
1361 }
1363}
1364
1365void FunctionEntryInstr::PrintTo(BaseTextBuffer* f) const {
1366 f->Printf("B%" Pd "[function entry]:%" Pd, block_id(), GetDeoptId());
1367 if (HasParallelMove()) {
1368 f->AddString("\n");
1369 parallel_move()->PrintTo(f);
1370 }
1372}
1373
1374void NativeEntryInstr::PrintTo(BaseTextBuffer* f) const {
1375 f->Printf("B%" Pd "[native function entry]:%" Pd, block_id(), GetDeoptId());
1376 if (HasParallelMove()) {
1377 f->AddString("\n");
1378 parallel_move()->PrintTo(f);
1379 }
1381}
1382
1383void FfiCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1384 f->AddString(" pointer=");
1385 InputAt(TargetAddressIndex())->PrintTo(f);
1386 if (marshaller_.ReturnsCompound()) {
1387 f->AddString(", compound_return_typed_data=");
1389 }
1390 intptr_t def_index = 0;
1391 for (intptr_t arg_index = 0; arg_index < marshaller_.num_args();
1392 arg_index++) {
1393 const auto& arg_location = marshaller_.Location(arg_index);
1394 const bool is_compound = arg_location.container_type().IsCompound();
1395 const intptr_t num_defs = marshaller_.NumDefinitions(arg_index);
1396 f->AddString(", ");
1397 if (is_compound) f->AddString("(");
1398 for (intptr_t i = 0; i < num_defs; i++) {
1399 InputAt(def_index)->PrintTo(f);
1400 if ((i + 1) < num_defs) f->AddString(", ");
1401 def_index++;
1402 }
1403 if (is_compound) f->AddString(")");
1404 f->AddString(" (@");
1405 arg_location.PrintTo(f);
1406 f->AddString(")");
1407 }
1408}
1409
1410void LeafRuntimeCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1411 f->AddString("target_address=");
1412 InputAt(TargetAddressIndex())->PrintTo(f);
1413 for (intptr_t i = 0, n = argument_representations_.length(); i < n; ++i) {
1414 f->AddString(", ");
1415 InputAt(i)->PrintTo(f);
1416 }
1417}
1418
1419void NativeReturnInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1420 if (marshaller_.NumReturnDefinitions() == 1) {
1421 InputAt(0)->PrintTo(f);
1422 } else {
1423 ASSERT_EQUAL(marshaller_.NumReturnDefinitions(), 2);
1424 f->AddString("(");
1425 InputAt(0)->PrintTo(f);
1426 f->AddString(", ");
1427 InputAt(1)->PrintTo(f);
1428 f->AddString(")");
1429 }
1430
1431 f->AddString(" (@");
1432 marshaller_.Location(compiler::ffi::kResultIndex).PrintTo(f);
1433 f->AddString(")");
1434}
1435
1436void NativeParameterInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1437 // Where the calling convention puts it.
1438 marshaller_.Location(marshaller_.ArgumentIndex(def_index_)).PrintTo(f);
1439 f->AddString(" at ");
1440 // Where the arguments are when pushed on the stack.
1441 marshaller_.NativeLocationOfNativeParameter(def_index_).PrintTo(f);
1442}
1443
1444void CatchBlockEntryInstr::PrintTo(BaseTextBuffer* f) const {
1445 f->Printf("B%" Pd "[target catch try_idx %" Pd " catch_try_idx %" Pd "]",
1447 if (HasParallelMove()) {
1448 f->AddString("\n");
1449 parallel_move()->PrintTo(f);
1450 }
1451
1453}
1454
1455void LoadIndexedUnsafeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1456 f->Printf("%s[", RegisterNames::RegisterName(base_reg()));
1457 index()->PrintTo(f);
1458 f->Printf(" + %" Pd "]", offset());
1459}
1460
1461void StoreIndexedUnsafeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1462 f->Printf("%s[", RegisterNames::RegisterName(base_reg()));
1463 index()->PrintTo(f);
1464 f->Printf(" + %" Pd "], ", offset());
1465 value()->PrintTo(f);
1466}
1467
1468void LoadIndexedInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1469 auto& cls =
1470 Class::Handle(IsolateGroup::Current()->class_table()->At(class_id()));
1471 if (!cls.IsNull()) {
1472 f->Printf("[%s] ", cls.ScrubbedNameCString());
1473 } else {
1474 f->Printf("[cid %" Pd "] ", class_id());
1475 }
1476 Instruction::PrintOperandsTo(f);
1477}
1478
1479void StoreIndexedInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1480 auto& cls =
1481 Class::Handle(IsolateGroup::Current()->class_table()->At(class_id()));
1482 if (!cls.IsNull()) {
1483 f->Printf("[%s] ", cls.ScrubbedNameCString());
1484 } else {
1485 f->Printf("[cid %" Pd "] ", class_id());
1486 }
1487 Instruction::PrintOperandsTo(f);
1488 if (!ShouldEmitStoreBarrier()) {
1489 f->AddString(", NoStoreBarrier");
1490 }
1491}
1492
1493void MemoryCopyInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1494 Instruction::PrintOperandsTo(f);
1495 auto& cls =
1496 Class::Handle(IsolateGroup::Current()->class_table()->At(dest_cid_));
1497 if (!cls.IsNull()) {
1498 f->Printf(", dest_cid=%s (%d)", cls.ScrubbedNameCString(), dest_cid_);
1499 } else {
1500 f->Printf(", dest_cid=%d", dest_cid_);
1501 }
1502 if (dest()->definition()->representation() == kUntagged) {
1503 f->Printf(" [untagged]");
1504 }
1505 cls = IsolateGroup::Current()->class_table()->At(src_cid_);
1506 if (!cls.IsNull()) {
1507 f->Printf(", src_cid=%s (%d)", cls.ScrubbedNameCString(), src_cid_);
1508 } else {
1509 f->Printf(", src_cid=%d", src_cid_);
1510 }
1511 if (src()->definition()->representation() == kUntagged) {
1512 f->Printf(" [untagged]");
1513 }
1514 if (element_size() != 1) {
1515 f->Printf(", element_size=%" Pd "", element_size());
1516 }
1517 if (unboxed_inputs()) {
1518 f->AddString(", unboxed_inputs");
1519 }
1520 if (can_overlap()) {
1521 f->AddString(", can_overlap");
1522 }
1523}
1524
1525void TailCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1526 const char* name = "<unknown code>";
1527 if (code_.IsStubCode()) {
1528 name = StubCode::NameOfStub(code_.EntryPoint());
1529 } else {
1530 const Object& owner = Object::Handle(code_.owner());
1531 if (owner.IsFunction()) {
1533 .ToFullyQualifiedCString();
1534 }
1535 }
1536 f->Printf("%s(", name);
1537 InputAt(0)->PrintTo(f);
1538 f->AddString(")");
1539}
1540
1541void Call1ArgStubInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1542 const char* name = "";
1543 switch (stub_id_) {
1545 name = "CloneSuspendState";
1546 break;
1547 case StubId::kInitAsync:
1548 name = "InitAsync";
1549 break;
1551 name = "InitAsyncStar";
1552 break;
1554 name = "InitSyncStar";
1555 break;
1557 name = "FfiAsyncCallbackSend";
1558 break;
1559 }
1560 f->Printf("%s(", name);
1561 operand()->PrintTo(f);
1562 f->AddString(")");
1563}
1564
1565void SuspendInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1566 const char* name = "";
1567 switch (stub_id_) {
1568 case StubId::kAwait:
1569 name = "Await";
1570 break;
1572 name = "AwaitWithTypeCheck";
1573 break;
1575 name = "YieldAsyncStar";
1576 break;
1578 name = "SuspendSyncStarAtStart";
1579 break;
1581 name = "SuspendSyncStarAtYield";
1582 break;
1583 }
1584 f->Printf("%s(", name);
1585 Definition::PrintOperandsTo(f);
1586 f->AddString(")");
1587}
1588
1589void MoveArgumentInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1590 f->Printf("%s <- ", location().ToCString());
1591 value()->PrintTo(f);
1592}
1593
1594void GotoInstr::PrintTo(BaseTextBuffer* f) const {
1595 if (HasParallelMove()) {
1596 parallel_move()->PrintTo(f);
1597 f->AddString(" ");
1598 }
1599 if (GetDeoptId() != DeoptId::kNone) {
1600 f->Printf("goto:%" Pd " B%" Pd "", GetDeoptId(), successor()->block_id());
1601 } else {
1602 f->Printf("goto: B%" Pd "", successor()->block_id());
1603 }
1604}
1605
1606void IndirectGotoInstr::PrintTo(BaseTextBuffer* f) const {
1607 if (GetDeoptId() != DeoptId::kNone) {
1608 f->Printf("igoto:%" Pd "(", GetDeoptId());
1609 } else {
1610 f->AddString("igoto:(");
1611 }
1612 InputAt(0)->PrintTo(f);
1613 f->AddString(")");
1614}
1615
1616void BranchInstr::PrintTo(BaseTextBuffer* f) const {
1617 f->Printf("%s ", DebugName());
1618 f->AddString("if ");
1619 comparison()->PrintTo(f);
1620
1621 f->Printf(" goto (%" Pd ", %" Pd ")", true_successor()->block_id(),
1622 false_successor()->block_id());
1623}
1624
1625void ParallelMoveInstr::PrintTo(BaseTextBuffer* f) const {
1626 f->Printf("%s ", DebugName());
1627 for (intptr_t i = 0; i < moves_.length(); i++) {
1628 if (i != 0) f->AddString(", ");
1629 moves_[i]->dest().PrintTo(f);
1630 f->AddString(" <- ");
1631 moves_[i]->src().PrintTo(f);
1632 }
1633}
1634
1635void Utf8ScanInstr::PrintTo(BaseTextBuffer* f) const {
1636 Definition::PrintTo(f);
1637 f->Printf(" [%s]", scan_flags_field_.Name());
1638}
1639
1640void Environment::PrintTo(BaseTextBuffer* f) const {
1641 f->AddString(" env={ ");
1642 int arg_count = 0;
1643 for (intptr_t i = 0; i < values_.length(); ++i) {
1644 if (i > 0) f->AddString(", ");
1645 if (values_[i]->definition()->IsMoveArgument()) {
1646 f->Printf("a%d", arg_count++);
1647 } else {
1648 values_[i]->PrintTo(f);
1649 }
1650 if ((locations_ != nullptr) && !locations_[i].IsInvalid()) {
1651 f->AddString(" [");
1652 locations_[i].PrintTo(f);
1653 f->AddString("]");
1654 }
1655 }
1656 f->AddString(" }");
1657 if (outer_ != nullptr) outer_->PrintTo(f);
1658}
1659
1660const char* Environment::ToCString() const {
1661 char buffer[1024];
1662 BufferFormatter bf(buffer, 1024);
1663 PrintTo(&bf);
1665}
1666
1667#else // defined(INCLUDE_IL_PRINTER)
1668
1669const char* Instruction::ToCString() const {
1670 return DebugName();
1671}
1672
1674 bool print_locations) {
1675 UNREACHABLE();
1676}
1677
1679 TokenPosition token_pos,
1680 Value* value,
1681 const AbstractType& dst_type,
1682 const String& dst_name,
1683 bool eliminated) {
1684 UNREACHABLE();
1685}
1686
1688 bool print_locations) {
1689 UNREACHABLE();
1690}
1691
1692void FlowGraphPrinter::PrintGraph(const char* phase, FlowGraph* flow_graph) {
1693 UNREACHABLE();
1694}
1695
1697 intptr_t num_checks_to_print) {
1698 UNREACHABLE();
1699}
1700
1702 const Function& function,
1703 uint8_t** compiler_pass_filter /* = nullptr */) {
1704 return false;
1705}
1706
1707#endif // defined(INCLUDE_IL_PRINTER)
1708
1709} // namespace dart
#define test(name)
int count
SkPoint pos
static int block_count(const SkSBlockAllocator< N > &pool)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define UNREACHABLE()
Definition assert.h:248
#define ASSERT_EQUAL(expected, actual)
Definition assert.h:309
intptr_t num_context_variables() const
Definition il.h:8344
const Class & cls() const
Definition il.h:7396
virtual intptr_t InputCount() const
Definition il.h:7399
intptr_t num_context_variables() const
Definition il.h:7555
virtual AliasIdentity Identity() const
Definition il.h:7283
Value * dst_type() const
Definition il.h:4405
const String & dst_name() const
Definition il.h:4412
Value * value() const
Definition il.h:4404
Value * function_type_arguments() const
Definition il.h:4409
Value * instantiator_type_arguments() const
Definition il.h:4406
Value * value() const
Definition il.h:4473
Value * function_type_arguments() const
Definition il.h:4322
Value * dst_name() const
Definition il.h:4325
Value * super_type() const
Definition il.h:4324
Value * sub_type() const
Definition il.h:4323
Value * instantiator_type_arguments() const
Definition il.h:4319
intptr_t length() const
Token::Kind op_kind() const
Definition il.h:8990
Value * right() const
Definition il.h:8988
Value * left() const
Definition il.h:8987
bool can_overflow() const
Definition il.h:9352
Value * right() const
Definition il.h:9350
Token::Kind op_kind() const
Definition il.h:9348
Value * left() const
Definition il.h:9349
bool is_truncating() const
Definition il.h:9358
Representation to() const
Definition il.h:11067
Representation from() const
Definition il.h:11066
intptr_t try_index() const
Definition il.h:1724
ParallelMoveInstr * parallel_move() const
Definition il.h:1683
bool HasParallelMove() const
Definition il.h:1685
intptr_t block_id() const
Definition il.h:1655
intptr_t stack_depth() const
Definition il.h:1750
void PrintInitialDefinitionsTo(BaseTextBuffer *f) const
TargetEntryInstr * false_successor() const
Definition il.h:4030
TargetEntryInstr * true_successor() const
Definition il.h:4029
ComparisonInstr * comparison() const
Definition il.h:4003
const Function & function() const
Definition il.h:5697
intptr_t index_scale() const
Definition il.h:7972
Value * operand() const
Definition il.h:11394
intptr_t catch_try_index() const
Definition il.h:2363
const CidRangeValue & cids() const
Definition il.h:10702
Value * value() const
Definition il.h:10701
Value * value() const
Definition il.h:10540
bool IsNullCheck() const
Definition il.h:10546
ComparisonInstr * comparison() const
Definition il.h:10920
ExceptionType exception_type() const
Definition il.h:10650
intptr_t stack_depth() const
Definition il.h:9857
intptr_t loop_depth() const
Definition il.h:9858
ClassPtr At(intptr_t cid) const
void PrintTo(BaseTextBuffer *f) const
const Object & value() const
Definition il.h:4212
Value * value() const
Definition il.h:4174
Range * constraint() const
Definition il.h:4175
bool HasTemp() const
Definition il.h:2483
bool HasSSATemp() const
Definition il.h:2490
Range * range_
Definition il.h:2674
intptr_t ssa_temp_index() const
Definition il.h:2485
bool HasType() const
Definition il.h:2512
static constexpr intptr_t kNone
Definition deopt_id.h:27
Value * class_id() const
Definition il.h:5044
const Function & interface_target() const
Definition il.h:5038
Value * value() const
Definition il.h:9053
MethodRecognizer::Kind op_kind() const
Definition il.h:9055
Value * value() const
Definition il.h:5812
intptr_t num_temps() const
Definition il.h:5814
void PrintTo(BaseTextBuffer *f) const
const char * ToCString() const
intptr_t index() const
Definition il.h:10281
intptr_t CompoundReturnTypedDataIndex() const
Definition il.h:6056
intptr_t TargetAddressIndex() const
Definition il.h:6051
static DART_FORCE_INLINE bool HasLifetimePosition(Instruction *instr)
Definition linearscan.h:74
static DART_FORCE_INLINE intptr_t GetLifetimePosition(const Instruction *instr)
Definition linearscan.h:78
static void PrintOneInstruction(Instruction *instr, bool print_locations)
static void PrintGraph(const char *phase, FlowGraph *flow_graph)
static void PrintCidRangeData(const CallTargets &ic_data, intptr_t num_checks_to_print=kPrintAll)
static bool ShouldPrint(const Function &function, uint8_t **compiler_pass_filter=nullptr)
static void PrintBlock(BlockEntryInstr *block, bool print_locations)
static constexpr intptr_t kPrintAll
Definition il_printer.h:23
FlowGraphPrinter(const FlowGraph &flow_graph, bool print_locations=false)
Definition il_printer.h:25
void PrintInstruction(Instruction *instr)
static void PrintICData(const ICData &ic_data, intptr_t num_checks_to_print=kPrintAll)
static void PrintTypeCheck(const ParsedFunction &parsed_function, TokenPosition token_pos, Value *value, const AbstractType &dst_type, const String &dst_name, bool eliminated)
const char * ToFullyQualifiedCString() const
Definition object.cc:9820
static const char * KindToCString(UntaggedFunction::Kind kind)
Definition object.cc:8477
bool HasSavedArgumentsDescriptor() const
Definition object.h:3253
UntaggedFunction::Kind kind() const
Definition object.h:3329
ArrayPtr saved_args_desc() const
Definition object.cc:8191
ParallelMoveInstr * parallel_move() const
Definition il.h:3717
bool HasParallelMove() const
Definition il.h:3719
JoinEntryInstr * successor() const
Definition il.h:3695
const Field & field() const
Definition il.h:6476
Value * value() const
Definition il.h:6474
Value * value() const
Definition il.h:9141
ComparisonInstr * comparison() const
Definition il.h:5434
CompileType * result_type() const
Definition il.h:4730
Code::EntryKind entry_kind() const
Definition il.h:4741
const ICData * ic_data() const
Definition il.h:4698
bool HasICData() const
Definition il.h:4699
const String & function_name() const
Definition il.h:4706
const AbstractType & type() const
Definition il.h:7245
Value * function_type_arguments() const
Definition il.h:7243
Value * instantiator_type_arguments() const
Definition il.h:7242
Value * value() const
Definition il.h:7241
Value * type_arguments() const
Definition il.h:8260
Value * instantiator_type_arguments() const
Definition il.h:8258
Value * function_type_arguments() const
Definition il.h:8259
const Class & instantiator_class() const
Definition il.h:8261
Value * function_type_arguments() const
Definition il.h:8207
const AbstractType & type() const
Definition il.h:8208
Value * instantiator_type_arguments() const
Definition il.h:8206
virtual intptr_t InputCount() const =0
intptr_t GetDeoptId() const
Definition il.h:1403
virtual Value * InputAt(intptr_t i) const =0
const char * ToCString() const
virtual Representation representation() const
Definition il.h:1254
Value * ArgumentValueAt(intptr_t index) const
Definition il.h:3417
virtual const char * DebugName() const =0
bool is_truncating() const
Definition il.h:10994
Representation to() const
Definition il.h:10993
Representation from() const
Definition il.h:10992
static IsolateGroup * Current()
Definition isolate.h:534
ClassTable * class_table() const
Definition isolate.h:491
GrowableArray< BlockEntryInstr * > predecessors_
Definition il.h:2092
intptr_t TargetAddressIndex() const
Definition il.h:6149
Value * object() const
Definition il.h:8018
const Slot & slot() const
Definition il.h:8096
bool IsImmutableLoad() const
Definition il.h:8129
InnerPointerAccess loads_inner_pointer() const
Definition il.h:8098
Value * instance() const
Definition il.h:8095
intptr_t class_id() const
Definition il.h:6759
Value * index() const
Definition il.h:3109
intptr_t offset() const
Definition il.h:3111
Register base_reg() const
Definition il.h:3110
const LocalVariable & local() const
Definition il.h:5765
const Field & field() const
Definition il.h:6639
Value * object() const
Definition il.h:7906
intptr_t offset() const
Definition il.h:7907
void PrintTo(BaseTextBuffer *f) const
Definition locations.cc:420
bool unboxed_inputs() const
Definition il.h:3198
Value * dest() const
Definition il.h:3190
intptr_t element_size() const
Definition il.h:3197
bool can_overlap() const
Definition il.h:3199
Value * src() const
Definition il.h:3189
static const char * KindToCString(Kind kind)
Value * value() const
Definition il.h:3359
Location location() const
Definition il.h:3356
const String & native_name() const
Definition il.h:5973
virtual Value * InputAt(intptr_t i) const
Definition il.h:3562
virtual const char * ToCString() const
Definition object.h:366
bool IsNull() const
Definition object.h:363
static Object & Handle()
Definition object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition object.h:325
const Location & location() const
Definition il.h:2928
bool is_alive() const
Definition il.h:2809
virtual Representation representation() const
Definition il.h:2817
const char * ToCString() const
void PrintTo(BaseTextBuffer *f) const
static const char * ToCString(const Range *range)
void PrintTo(BaseTextBuffer *f) const
Value * value() const
Definition il.h:4138
static const char * RegisterName(Register reg)
Definition constants.h:46
intptr_t mask() const
Definition il.h:11305
virtual intptr_t InputCount() const
Definition il.cc:8299
virtual Value * InputAt(intptr_t i) const
Definition il.h:11299
Kind kind() const
Definition il.h:11304
CompileType * result_type() const
Definition il.h:5603
const Function & function() const
Definition il.h:5574
Code::EntryKind entry_kind() const
Definition il.h:5617
InnerPointerAccess stores_inner_pointer() const
Definition il.h:6406
Value * value() const
Definition il.h:6375
Value * instance() const
Definition il.h:6373
const Slot & slot() const
Definition il.h:6374
bool ShouldEmitStoreBarrier() const
Definition il.h:7045
intptr_t class_id() const
Definition il.h:7042
intptr_t offset() const
Definition il.h:3056
Value * value() const
Definition il.h:3054
Register base_reg() const
Definition il.h:3055
Value * index() const
Definition il.h:3053
Value * value() const
Definition il.h:5914
const LocalVariable & local() const
Definition il.h:5913
const Field & field() const
Definition il.h:6685
Value * value() const
Definition il.h:6686
bool needs_number_check() const
Definition il.h:5107
static const char * NameOfStub(uword entry_point)
Definition stub_code.cc:330
virtual intptr_t InputCount() const
Definition il.h:7350
intptr_t type_args_len() const
Definition il.h:4596
intptr_t ArgumentCount() const
Definition il.h:4568
virtual Value * InputAt(intptr_t i) const
Definition il.h:1509
bool calls_initializer() const
Definition il.h:6579
const ZoneGrowableArray< intptr_t > & cid_results() const
Definition il.h:5185
Zone * zone() const
static Thread * Current()
Definition thread.h:361
static const char * Str(Kind tok)
Definition token.h:269
Value * value() const
Definition il.h:9780
Token::Kind op_kind() const
Definition il.h:9781
Value * value() const
Definition il.h:9192
Token::Kind op_kind() const
Definition il.h:9193
bool is_truncating() const
Definition il.h:8724
intptr_t lane() const
Definition il.h:10362
Definition * definition() const
Definition il.h:103
const char * ToCString() const
InputsArray inputs_
Definition il.h:2782
intptr_t InputCount() const
Definition il.h:2776
Value * InputAt(intptr_t i) const
Definition il.h:2777
char * MakeCopyOfString(const char *str)
Definition zone.cc:270
ElementType * Alloc(intptr_t length)
#define THR_Print(format,...)
Definition log.h:20
#define ASSERT(E)
struct MyStruct a[10]
glong glong end
static const uint8_t buffer[]
uint8_t value
void PrintTo(FlValue *v, std::ostream *os)
Definition fl_test.cc:78
uint32_t * target
#define DECLARE_FLAG(type, name)
Definition flags.h:14
#define DEFINE_FLAG(type, name, default_value, comment)
Definition flags.h:16
Dart_NativeFunction function
Definition fuchsia.cc:51
const char * name
Definition fuchsia.cc:50
#define CASE(Arity, Mask, Name, Args, Result)
#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs)
Definition il.h:11773
#define FOR_EACH_INSTRUCTION(M)
Definition il.h:405
#define SIMD_OP_LIST(M, BINARY_OP)
Definition il.h:11195
size_t length
ImplicitString Name
Definition DMSrcSink.h:38
const intptr_t kResultIndex
Definition marshaller.h:28
const char *const name
DART_EXPORT bool IsNull(Dart_Handle object)
@ kNoStoreBarrier
Definition il.h:6252
const intptr_t cid
static constexpr intptr_t kInvalidTryIndex
#define Px
Definition globals.h:410
#define Pd64
Definition globals.h:416
#define Pd
Definition globals.h:408
#define T
static const char * ToCString(Representation rep)
Definition locations.cc:129