// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/compiler/backend/il_printer.h"

#include <tuple>

#include "vm/class_id.h"
#include "vm/compiler/api/print_filter.h"
#include "vm/compiler/backend/il.h"
#include "vm/compiler/backend/linearscan.h"
#include "vm/compiler/backend/range_analysis.h"
#include "vm/compiler/ffi/native_calling_convention.h"
#include "vm/os.h"
#include "vm/parser.h"

namespace dart {

#if defined(INCLUDE_IL_PRINTER)
DEFINE_FLAG(bool,
            display_sorted_ic_data,
            false,
            "Calls display a unary, sorted-by count form of ICData");
DEFINE_FLAG(bool, print_environments, false, "Print SSA environments.");
DEFINE_FLAG(bool,
            print_flow_graph_as_json,
            false,
            "Use machine readable output when printing IL graphs.");
DEFINE_FLAG(bool, print_redundant_il, false, "Print redundant IL instructions");

DECLARE_FLAG(bool, trace_inlining_intervals);

static bool IsRedundant(Instruction* instr) {
  if (auto constant = instr->AsConstant()) {
    return !constant->HasUses();
  } else if (auto move = instr->AsParallelMove()) {
    return move->IsRedundant();
  } else {
    return false;
  }
}

static bool ShouldPrintInstruction(Instruction* instr) {
  return FLAG_print_redundant_il || !IsRedundant(instr);
}

class IlTestPrinter : public AllStatic {
 public:
  static void PrintGraph(const char* phase, FlowGraph* flow_graph) {
    JSONWriter writer;
    writer.OpenObject();
    writer.PrintProperty("p", phase);
    writer.PrintProperty("f", flow_graph->function().ToFullyQualifiedCString());
    writer.OpenArray("b");
    for (auto block : flow_graph->reverse_postorder()) {
      PrintBlock(&writer, block);
    }
    writer.CloseArray();
    const auto& codegen_order = *flow_graph->CodegenBlockOrder();
    if (!codegen_order.is_empty() &&
        (&codegen_order != &flow_graph->reverse_postorder())) {
      writer.OpenArray("cbo");
      const auto block_count = flow_graph->reverse_postorder().length();
      for (auto block : codegen_order) {
        writer.PrintValue64((block_count - 1) - block->postorder_number());
      }
      writer.CloseArray();
    }
    writer.OpenObject("desc");
    AttributesSerializer(&writer).WriteDescriptors();
    writer.CloseObject();
    writer.OpenObject("flags");
    writer.PrintPropertyBool("nnbd", true);
    writer.CloseObject();
    writer.CloseObject();
    THR_Print("%s\n", writer.ToCString());
  }

  static void PrintBlock(JSONWriter* writer, BlockEntryInstr* block) {
    writer->OpenObject();
    writer->PrintProperty64("b", block->block_id());
    writer->PrintProperty("o", block->DebugName());
    if (auto block_with_defs = block->AsBlockEntryWithInitialDefs()) {
      if (block_with_defs->initial_definitions() != nullptr &&
          block_with_defs->initial_definitions()->length() > 0) {
        writer->OpenArray("d");
        for (auto defn : *block_with_defs->initial_definitions()) {
          if (ShouldPrintInstruction(defn)) {
            PrintInstruction(writer, defn);
          }
        }
        writer->CloseArray();
      }
    }
    if (auto try_entry = block->AsTryEntry()) {
      writer->PrintProperty("tryBody", try_entry->try_body()->block_id());
      writer->PrintProperty("catches", try_entry->catch_target()->block_id());
    }
    writer->OpenArray("is");
    if (auto join = block->AsJoinEntry()) {
      for (PhiIterator it(join); !it.Done(); it.Advance()) {
        if (ShouldPrintInstruction(it.Current())) {
          PrintInstruction(writer, it.Current());
        }
      }
    }
    for (auto instr : block->instructions()) {
      if (instr->ArgumentCount() != 0 && instr->GetMoveArguments() != nullptr) {
        for (auto move_arg : *(instr->GetMoveArguments())) {
          PrintInstruction(writer, move_arg);
        }
      }
      if (ShouldPrintInstruction(instr) && !instr->IsMoveArgument()) {
        PrintInstruction(writer, instr);
      }
    }
    writer->CloseArray();
    writer->CloseObject();
  }

  static void PrintInstruction(JSONWriter* writer,
                               Instruction* instr,
                               const char* name = nullptr) {
    writer->OpenObject(name);
    if (auto defn = instr->AsDefinition()) {
      if (defn->ssa_temp_index() != -1) {
        writer->PrintProperty("v", defn->ssa_temp_index());
      }

      if (defn->HasType()) {
        writer->OpenObject("T");
        defn->Type()->PrintTo(writer);
        writer->CloseObject();
      }
    }
    writer->PrintProperty("o", instr->DebugName());
    if (auto branch = instr->AsBranch()) {
      PrintInstruction(writer, branch->condition(), "cc");
    } else {
      if (instr->InputCount() != 0) {
        writer->OpenArray("i");
        for (intptr_t i = 0; i < instr->InputCount(); i++) {
          writer->PrintValue(instr->InputAt(i)->definition()->ssa_temp_index());
        }
        writer->CloseArray();
      } else if (instr->ArgumentCount() != 0 &&
                 instr->GetMoveArguments() != nullptr) {
        writer->OpenArray("i");
        for (intptr_t i = 0; i < instr->ArgumentCount(); i++) {
          writer->PrintValue(
              instr->ArgumentValueAt(i)->definition()->ssa_temp_index());
        }
        writer->CloseArray();
      }
      AttributesSerializer serializer(writer);
      instr->Accept(&serializer);
    }
    if (instr->SuccessorCount() > 0) {
      writer->OpenArray("s");
      for (auto succ : instr->successors()) {
        writer->PrintValue(succ->block_id());
      }
      writer->CloseArray();
    }
    writer->CloseObject();
  }

  template <typename T>
  class HasGetAttributes {
    template <typename U>
    static std::true_type test(decltype(&U::GetAttributes));
    template <typename U>
    static std::false_type test(...);

   public:
    static constexpr bool value = decltype(test<T>(nullptr))::value;
  };

  class AttributesSerializer : public InstructionVisitor {
   public:
    explicit AttributesSerializer(JSONWriter* writer) : writer_(writer) {}

    void WriteDescriptors() {
#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs)                            \
  WriteDescriptor<ShortName##Instr>(#ShortName);

      FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION);

#undef DECLARE_VISIT_INSTRUCTION
    }

#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs)                            \
  virtual void Visit##ShortName(ShortName##Instr* instr) { Write(instr); }

    FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)

#undef DECLARE_VISIT_INSTRUCTION

   private:
    void WriteAttribute(const char* value) { writer_->PrintValue(value); }

    void WriteAttribute(intptr_t value) { writer_->PrintValue(value); }

    void WriteAttribute(bool value) { writer_->PrintValueBool(value); }

    void WriteAttribute(Token::Kind kind) {
      writer_->PrintValue(Token::Str(kind));
    }

    void WriteAttribute(Representation rep) {
      writer_->PrintValue(RepresentationUtils::ToCString(rep));
    }

    static const char* LocationKindAsString(const Location& loc) {
      if (loc.IsConstant()) {
        return "C";
      } else if (loc.IsPairLocation()) {
        auto pair = loc.AsPairLocation();
        return Thread::Current()->zone()->PrintToString(
            "(%s, %s)", LocationKindAsString(pair->At(0)),
            LocationKindAsString(pair->At(0)));
      } else {
        switch (loc.kind()) {
          case Location::kUnallocated:
            return ".";
          case Location::kStackSlot:
            return "stack(word)";
          case Location::kDoubleStackSlot:
            return "stack(f64)";
          case Location::kQuadStackSlot:
            return "stack(f128)";
          case Location::kRegister:
            return "reg(cpu)";
          case Location::kFpuRegister:
            return "reg(fpu)";
          default:
            return "?";
        }
      }
    }

    void WriteAttribute(const Location& loc) {
      writer_->PrintValue(LocationKindAsString(loc));
    }

    void WriteAttribute(const Slot* slot) { writer_->PrintValue(slot->Name()); }

    void WriteAttribute(const Function* function) {
      writer_->PrintValue(function->QualifiedUserVisibleNameCString());
    }

    void WriteAttribute(const Object* obj) {
      if (obj->IsNull()) {
        writer_->PrintValueNull();
      } else if (obj->IsBool()) {
        writer_->PrintValueBool(Bool::Cast(*obj).value());
      } else if (obj->IsInteger()) {
        auto value = Integer::Cast(*obj).Value();
        // PrintValue64 and PrintValue will check if integer is representable
        // as a JS number, which is too strict. We don't actually need
        // such checks because we only load resulting JSON in Dart.
        writer_->buffer()->Printf("%" Pd64 "", value);
      } else if (obj->IsString()) {
        const auto& str = String::Cast(*obj);
        writer_->PrintValueStr(str, 0, str.Length());
      } else {
        const auto& cls = Class::Handle(obj->clazz());
        writer_->PrintfValue("Instance of %s", cls.UserVisibleNameCString());
      }
    }

    template <typename... Ts>
    void WriteTuple(const std::tuple<Ts...>& tuple) {
      std::apply(
          [&](Ts const&... elements) { (WriteAttribute(elements), ...); },
          tuple);
    }

    template <typename T,
              typename = typename std::enable_if_t<HasGetAttributes<T>::value>>
    void Write(T* instr) {
      writer_->OpenArray("d");
      WriteTuple(instr->GetAttributes());
      writer_->CloseArray();
    }

    void Write(Instruction* instr) {
      // Default, do nothing.
    }

    void WriteAttributeName(const char* str) {
      ASSERT(str != nullptr);
      // To simplify the declaring side, we assume the string might be directly
      // stringized from one of the following expression forms:
      //
      // * &name()
      // * name()
      // * name_
      //
      // Remove the non-name parts of the above before printing.
      const intptr_t start = str[0] == '&' ? 1 : 0;
      intptr_t end = strlen(str);
      switch (str[end - 1]) {
        case ')':
          ASSERT(end >= 2);
          ASSERT_EQUAL(str[end - 2], '(');
          end -= 2;
          break;
        case '_':
          // Strip off the final _ from a direct private field access.
          end -= 1;
          break;
        default:
          break;
      }
      writer_->PrintValue(str + start, end - start);
    }

    template <typename... Ts>
    void WriteAttributeNames(const std::tuple<Ts...>& tuple) {
      std::apply(
          [&](Ts const&... elements) { (WriteAttributeName(elements), ...); },
          tuple);
    }

    template <typename T>
    void WriteDescriptor(
        const char* name,
        typename std::enable_if_t<HasGetAttributes<T>::value>* = nullptr) {
      writer_->OpenArray(name);
      WriteAttributeNames(T::GetAttributeNames());
      writer_->CloseArray();
    }

    template <typename T>
    void WriteDescriptor(
        const char* name,
        typename std::enable_if_t<!HasGetAttributes<T>::value>* = nullptr) {}

    JSONWriter* writer_;
  };
};

bool FlowGraphPrinter::ShouldPrint(
    const Function& function,
    uint8_t** compiler_pass_filter /* = nullptr */) {
  return compiler::PrintFilter::ShouldPrint(function, compiler_pass_filter);
}

void FlowGraphPrinter::PrintGraph(const char* phase, FlowGraph* flow_graph) {
  LogBlock lb;
  if (FLAG_print_flow_graph_as_json) {
    IlTestPrinter::PrintGraph(phase, flow_graph);
  } else {
    THR_Print("*** BEGIN CFG\n%s\n", phase);
    FlowGraphPrinter printer(*flow_graph);
    printer.PrintBlocks();
    THR_Print("*** END CFG\n");
  }
  fflush(stdout);
}

void FlowGraphPrinter::PrintBlock(BlockEntryInstr* block,
                                  bool print_locations) {
  // Print the block entry.
  PrintOneInstruction(block, print_locations);
  THR_Print("\n");
  // And all the successors in the block.
  for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
    Instruction* current = it.Current();

    // Skip redundant parallel moves.
    if (!ShouldPrintInstruction(current)) {
      continue;
    }

    PrintOneInstruction(current, print_locations);
    THR_Print("\n");
  }
}

void FlowGraphPrinter::PrintBlocks() {
  if (!function_.IsNull()) {
    THR_Print("==== %s (%s", function_.ToFullyQualifiedCString(),
              Function::KindToCString(function_.kind()));
    // Output saved arguments descriptor information for dispatchers that
    // have it, so it's easy to see which dispatcher this graph represents.
    if (function_.HasSavedArgumentsDescriptor()) {
      const auto& args_desc_array = Array::Handle(function_.saved_args_desc());
      const ArgumentsDescriptor args_desc(args_desc_array);
      THR_Print(", %s", args_desc.ToCString());
    }
    THR_Print(")\n");
  }

  for (intptr_t i = 0; i < block_order_.length(); ++i) {
    PrintBlock(block_order_[i], print_locations_);
  }
}

void FlowGraphPrinter::PrintInstruction(Instruction* instr) {
  PrintOneInstruction(instr, print_locations_);
}

void FlowGraphPrinter::PrintOneInstruction(Instruction* instr,
                                           bool print_locations) {
  char str[4000];
  BufferFormatter f(str, sizeof(str));
  if (FlowGraphAllocator::HasLifetimePosition(instr)) {
    f.Printf("%3" Pd ": ", FlowGraphAllocator::GetLifetimePosition(instr));
  }
  if (!instr->IsBlockEntry()) {
    f.Printf("    ");
  }
  if (auto* const block = instr->AsBlockEntryWithInitialDefs()) {
    block->PrintBlockHeaderTo(&f);
    // Output and clear the buffer after each internal definition, as otherwise
    // too many internal definitions could cause truncation in the output.
    auto callback = [](BaseTextBuffer* f) {
      THR_Print("%s", f->buffer());
      f->Clear();
    };
    block->PrintInitialDefinitionsTo(&f, callback);
  } else {
    instr->PrintTo(&f);
  }
  if (FLAG_print_environments && (instr->env() != nullptr)) {
    instr->env()->PrintTo(&f);
  }
  if (print_locations && (instr->HasLocs())) {
    instr->locs()->PrintTo(&f);
  }
  if (FLAG_trace_inlining_intervals) {
    f.Printf(" iid: %" Pd "", instr->inlining_id());
  }
  THR_Print("%s", f.buffer());
}

void FlowGraphPrinter::PrintTypeCheck(const ParsedFunction& parsed_function,
                                      TokenPosition token_pos,
                                      Value* value,
                                      const AbstractType& dst_type,
                                      const String& dst_name,
                                      bool eliminated) {
  const char* compile_type_name = "unknown";
  if (value != nullptr && value->reaching_type_ != nullptr) {
    compile_type_name = value->reaching_type_->ToCString();
  }
  THR_Print(
      "%s type check: compile type %s is %s specific than "
      "type '%s' of '%s'.\n",
      eliminated ? "Eliminated" : "Generated", compile_type_name,
      eliminated ? "more" : "not more", dst_type.NameCString(),
      dst_name.ToCString());
}

static void PrintTargetsHelper(BaseTextBuffer* f,
                               const CallTargets& targets,
                               intptr_t num_checks_to_print) {
  f->AddString(" Targets[");
  f->Printf("%" Pd ": ", targets.length());
  Function& target = Function::Handle();
  if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
      (num_checks_to_print > targets.length())) {
    num_checks_to_print = targets.length();
  }
  for (intptr_t i = 0; i < num_checks_to_print; i++) {
    const CidRange& range = targets[i];
    const auto target_info = targets.TargetAt(i);
    const intptr_t count = target_info->count;
    target = target_info->target->ptr();
    if (i > 0) {
      f->AddString(" | ");
    }
    if (range.IsSingleCid()) {
      const Class& cls = Class::Handle(
          IsolateGroup::Current()->class_table()->At(range.cid_start));
      f->Printf("%s", String::Handle(cls.Name()).ToCString());
      f->Printf(" cid %" Pd " cnt:%" Pd " trgt:'%s'", range.cid_start, count,
                target.ToQualifiedCString());
    } else {
      const Class& cls = Class::Handle(target.Owner());
      f->Printf("cid %" Pd "-%" Pd " %s", range.cid_start, range.cid_end,
                String::Handle(cls.Name()).ToCString());
      f->Printf(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString());
    }

    if (target_info->exactness.IsTracking()) {
      f->Printf(" %s", target_info->exactness.ToCString());
    }
  }
  if (num_checks_to_print < targets.length()) {
    f->AddString("...");
  }
  f->AddString("]");
}

static void PrintCidsHelper(BaseTextBuffer* f,
                            const Cids& targets,
                            intptr_t num_checks_to_print) {
  f->AddString(" Cids[");
  f->Printf("%" Pd ": ", targets.length());
  if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
      (num_checks_to_print > targets.length())) {
    num_checks_to_print = targets.length();
  }
  for (intptr_t i = 0; i < num_checks_to_print; i++) {
    const CidRange& range = targets[i];
    if (i > 0) {
      f->AddString(" | ");
    }
    const Class& cls = Class::Handle(
        IsolateGroup::Current()->class_table()->At(range.cid_start));
    f->Printf("%s etc. ", String::Handle(cls.Name()).ToCString());
    if (range.IsSingleCid()) {
      f->Printf(" cid %" Pd, range.cid_start);
    } else {
      f->Printf(" cid %" Pd "-%" Pd, range.cid_start, range.cid_end);
    }
  }
  if (num_checks_to_print < targets.length()) {
    f->AddString("...");
  }
  f->AddString("]");
}

static void PrintICDataHelper(BaseTextBuffer* f,
                              const ICData& ic_data,
                              intptr_t num_checks_to_print) {
  f->AddString(" IC[");
  if (ic_data.is_tracking_exactness()) {
    f->Printf(
        "(%s) ",
        AbstractType::Handle(ic_data.receivers_static_type()).ToCString());
  }
  f->Printf("%" Pd ": ", ic_data.NumberOfChecks());
  Function& target = Function::Handle();
  if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
      (num_checks_to_print > ic_data.NumberOfChecks())) {
    num_checks_to_print = ic_data.NumberOfChecks();
  }
  for (intptr_t i = 0; i < num_checks_to_print; i++) {
    GrowableArray<intptr_t> class_ids;
    ic_data.GetCheckAt(i, &class_ids, &target);
    const intptr_t count = ic_data.GetCountAt(i);
    if (i > 0) {
      f->AddString(" | ");
    }
    for (intptr_t k = 0; k < class_ids.length(); k++) {
      if (k > 0) {
        f->AddString(", ");
      }
      const Class& cls = Class::Handle(
          IsolateGroup::Current()->class_table()->At(class_ids[k]));
      f->Printf("%s", String::Handle(cls.Name()).ToCString());
    }
    f->Printf(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString());
    if (ic_data.is_tracking_exactness()) {
      f->Printf(" %s", ic_data.GetExactnessAt(i).ToCString());
    }
  }
  if (num_checks_to_print < ic_data.NumberOfChecks()) {
    f->AddString("...");
  }
  f->AddString("]");
}

static void PrintICDataSortedHelper(BaseTextBuffer* f,
                                    const ICData& ic_data_orig) {
  const ICData& ic_data =
      ICData::Handle(ic_data_orig.AsUnaryClassChecksSortedByCount());
  f->Printf(" IC[n:%" Pd "; ", ic_data.NumberOfChecks());
  for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
    const intptr_t count = ic_data.GetCountAt(i);
    const intptr_t cid = ic_data.GetReceiverClassIdAt(i);
    const Class& cls =
        Class::Handle(IsolateGroup::Current()->class_table()->At(cid));
    f->Printf("%s : %" Pd ", ", String::Handle(cls.Name()).ToCString(), count);
  }
  f->AddString("]");
}

void FlowGraphPrinter::PrintICData(const ICData& ic_data,
                                   intptr_t num_checks_to_print) {
  char buffer[1024];
  BufferFormatter f(buffer, sizeof(buffer));
  PrintICDataHelper(&f, ic_data, num_checks_to_print);
  THR_Print("%s ", buffer);
  const Array& a = Array::Handle(ic_data.arguments_descriptor());
  THR_Print(" arg-desc %" Pd "\n", a.Length());
}

void FlowGraphPrinter::PrintCidRangeData(const CallTargets& targets,
                                         intptr_t num_checks_to_print) {
  char buffer[1024];
  BufferFormatter f(buffer, sizeof(buffer));
  PrintTargetsHelper(&f, targets, num_checks_to_print);
  THR_Print("%s ", buffer);
  // TODO(erikcorry): Print args descriptor.
}

static void PrintUse(BaseTextBuffer* f, const Definition& definition) {
  if (definition.HasSSATemp()) {
    f->Printf("v%" Pd "", definition.ssa_temp_index());
  } else if (definition.HasTemp()) {
    f->Printf("t%" Pd "", definition.temp_index());
  }
}

const char* Instruction::ToCString() const {
  char buffer[1024];
  BufferFormatter f(buffer, sizeof(buffer));
  PrintTo(&f);
  return Thread::Current()->zone()->MakeCopyOfString(buffer);
}

void Instruction::PrintTo(BaseTextBuffer* f) const {
  if (GetDeoptId() != DeoptId::kNone) {
    f->Printf("%s:%" Pd "(", DebugName(), GetDeoptId());
  } else {
    f->Printf("%s(", DebugName());
  }
  PrintOperandsTo(f);
  f->AddString(")");
}

void Instruction::PrintOperandsTo(BaseTextBuffer* f) const {
  for (int i = 0; i < InputCount(); ++i) {
    if (i > 0) f->AddString(", ");
    if (InputAt(i) != nullptr) InputAt(i)->PrintTo(f);
  }
}

void Definition::PrintTo(BaseTextBuffer* f) const {
  PrintUse(f, *this);
  if (HasSSATemp() || HasTemp()) f->AddString(" <- ");
  if (GetDeoptId() != DeoptId::kNone) {
    f->Printf("%s:%" Pd "(", DebugName(), GetDeoptId());
  } else {
    f->Printf("%s(", DebugName());
  }
  PrintOperandsTo(f);
  f->AddString(")");
  if (range_ != nullptr) {
    f->AddString(" ");
    range_->PrintTo(f);
  }

  if (representation() != kNoRepresentation && representation() != kTagged) {
    f->Printf(" %s", RepresentationUtils::ToCString(representation()));
  } else if (type_ != nullptr) {
    f->AddString(" ");
    type_->PrintTo(f);
  }
}

void CheckNullInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Definition::PrintOperandsTo(f);
  switch (exception_type()) {
    case kNoSuchMethod:
      f->AddString(", NoSuchMethodError");
      break;
    case kArgumentError:
      f->AddString(", ArgumentError");
      break;
    case kCastError:
      f->AddString(", CastError");
      break;
  }
}

void Definition::PrintOperandsTo(BaseTextBuffer* f) const {
  for (int i = 0; i < InputCount(); ++i) {
    if (i > 0) f->AddString(", ");
    if (InputAt(i) != nullptr) {
      InputAt(i)->PrintTo(f);
    }
  }
}

void RedefinitionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Definition::PrintOperandsTo(f);
  if (constrained_type_ != nullptr) {
    f->Printf(" ^ %s", constrained_type_->ToCString());
  }
}

void ReachabilityFenceInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  value()->PrintTo(f);
}

const char* Value::ToCString() const {
  char buffer[1024];
  BufferFormatter f(buffer, sizeof(buffer));
  PrintTo(&f);
  return Thread::Current()->zone()->MakeCopyOfString(buffer);
}

void Value::PrintTo(BaseTextBuffer* f) const {
  PrintUse(f, *definition());

  if ((reaching_type_ != nullptr) && (reaching_type_ != definition()->type_)) {
    f->AddString(" ");
    reaching_type_->PrintTo(f);
  }
}

void ConstantInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  const char* cstr = value().ToCString();
  const char* new_line = strchr(cstr, '\n');
  if (new_line == nullptr) {
    f->Printf("#%s", cstr);
  } else {
    const intptr_t pos = new_line - cstr;
    char* buffer = Thread::Current()->zone()->Alloc<char>(pos + 1);
    strncpy(buffer, cstr, pos);
    buffer[pos] = '\0';
    f->Printf("#%s\\n...", buffer);
  }
}

void ConstraintInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  value()->PrintTo(f);
  f->AddString(" ^ ");
  constraint()->PrintTo(f);
}

void Range::PrintTo(BaseTextBuffer* f) const {
  f->AddString("[");
  min_.PrintTo(f);
  f->AddString(", ");
  max_.PrintTo(f);
  f->AddString("]");
}

const char* Range::ToCString(const Range* range) {
  if (range == nullptr) return "[_|_, _|_]";

  char buffer[256];
  BufferFormatter f(buffer, sizeof(buffer));
  range->PrintTo(&f);
  return Thread::Current()->zone()->MakeCopyOfString(buffer);
}

void RangeBoundary::PrintTo(BaseTextBuffer* f) const {
  switch (kind_) {
    case kSymbol:
      f->Printf("v%" Pd "",
                reinterpret_cast<Definition*>(value_)->ssa_temp_index());
      if (offset_ != 0) f->Printf("%+" Pd64 "", offset_);
      break;
    case kConstant:
      f->Printf("%" Pd64 "", value_);
      break;
    case kUnknown:
      f->AddString("_|_");
      break;
  }
}

const char* RangeBoundary::ToCString() const {
  char buffer[256];
  BufferFormatter f(buffer, sizeof(buffer));
  PrintTo(&f);
  return Thread::Current()->zone()->MakeCopyOfString(buffer);
}

void MakeTempInstr::PrintOperandsTo(BaseTextBuffer* f) const {}

void DropTempsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%" Pd "", num_temps());
  if (value() != nullptr) {
    f->AddString(", ");
    value()->PrintTo(f);
  }
}

void AssertAssignableInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  value()->PrintTo(f);
  f->AddString(", ");
  dst_type()->PrintTo(f);
  f->Printf(", '%s',", dst_name().ToCString());
  f->AddString(" instantiator_type_args(");
  instantiator_type_arguments()->PrintTo(f);
  f->AddString("), function_type_args(");
  function_type_arguments()->PrintTo(f);
  f->AddString(")");
}

void AssertSubtypeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  sub_type()->PrintTo(f);
  f->AddString(", ");
  super_type()->PrintTo(f);
  f->AddString(", ");
  dst_name()->PrintTo(f);
  f->AddString(", instantiator_type_args(");
  instantiator_type_arguments()->PrintTo(f);
  f->AddString("), function_type_args(");
  function_type_arguments()->PrintTo(f);
  f->AddString(")");
}

void ClosureCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  if (FLAG_precompiled_mode) {
    f->AddString(" closure=");
  } else {
    f->AddString(" function=");
  }
  InputAt(InputCount() - 1)->PrintTo(f);
  f->Printf("<%" Pd ">", type_args_len());
  for (intptr_t i = 0; i < ArgumentCount(); ++i) {
    f->AddString(", ");
    ArgumentValueAt(i)->PrintTo(f);
  }
}

void InstanceCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf(" %s<%" Pd ">", function_name().ToCString(), type_args_len());
  for (intptr_t i = 0; i < ArgumentCount(); ++i) {
    f->AddString(", ");
    ArgumentValueAt(i)->PrintTo(f);
  }
  if (HasICData()) {
    if (FLAG_display_sorted_ic_data) {
      PrintICDataSortedHelper(f, *ic_data());
    } else {
      PrintICDataHelper(f, *ic_data(), FlowGraphPrinter::kPrintAll);
    }
  }
  if (result_type() != nullptr) {
    f->Printf(", result_type = %s", result_type()->ToCString());
  }
  if (entry_kind() == Code::EntryKind::kUnchecked) {
    f->AddString(" using unchecked entrypoint");
  }
}

void PolymorphicInstanceCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf(" %s<%" Pd ">", function_name().ToCString(), type_args_len());
  for (intptr_t i = 0; i < ArgumentCount(); ++i) {
    f->AddString(", ");
    ArgumentValueAt(i)->PrintTo(f);
  }
  PrintTargetsHelper(f, targets_, FlowGraphPrinter::kPrintAll);
  if (complete()) {
    f->AddString(" COMPLETE");
  }
  if (entry_kind() == Code::EntryKind::kUnchecked) {
    f->AddString(" using unchecked entrypoint");
  }
}

void DispatchTableCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  const String& name =
      String::Handle(interface_target().QualifiedUserVisibleName());
  f->AddString(" cid=");
  class_id()->PrintTo(f);
  f->Printf(" %s<%" Pd ">", name.ToCString(), type_args_len());
  for (intptr_t i = 0; i < ArgumentCount(); ++i) {
    f->AddString(", ");
    ArgumentValueAt(i)->PrintTo(f);
  }
}

void StrictCompareInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s, ", Token::Str(kind()));
  left()->PrintTo(f);
  f->AddString(", ");
  right()->PrintTo(f);
  if (needs_number_check()) {
    f->Printf(", with number check");
  }
}

void TestCidsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  value()->PrintTo(f);
  f->Printf(" %s [", Token::Str(kind()));
  intptr_t length = cid_results().length();
  for (intptr_t i = 0; i < length; i += 2) {
    f->Printf("0x%" Px ":%s ", cid_results()[i],
              cid_results()[i + 1] == 0 ? "false" : "true");
  }
  f->AddString("] ");
  if (CanDeoptimize()) {
    ASSERT(deopt_id() != DeoptId::kNone);
    f->AddString("else deoptimize ");
  } else {
    ASSERT(deopt_id() == DeoptId::kNone);
    f->Printf("else %s ", cid_results()[length - 1] != 0 ? "false" : "true");
  }
}

void TestRangeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  value()->PrintTo(f);
  f->Printf(" %s [%" Pd "-%" Pd "]", kind() == Token::kIS ? "in" : "not in",
            lower_, upper_);
}

void EqualityCompareInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  left()->PrintTo(f);
  f->Printf(" %s ", Token::Str(kind()));
  right()->PrintTo(f);
}

void StaticCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf(" %s<%" Pd "> ", String::Handle(function().name()).ToCString(),
            type_args_len());
  for (intptr_t i = 0; i < ArgumentCount(); ++i) {
    if (i > 0) f->AddString(", ");
    ArgumentValueAt(i)->PrintTo(f);
  }
  if (entry_kind() == Code::EntryKind::kUnchecked) {
    f->AddString(", using unchecked entrypoint");
  }
  if (function().recognized_kind() != MethodRecognizer::kUnknown) {
    f->Printf(", recognized_kind = %s",
              MethodRecognizer::KindToCString(function().recognized_kind()));
  }
  if (result_type() != nullptr) {
    f->Printf(", result_type = %s", result_type()->ToCString());
  }
}

void CachableIdempotentCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf(" %s<%" Pd "> ", String::Handle(function().name()).ToCString(),
            type_args_len());
  for (intptr_t i = 0; i < ArgumentCount(); ++i) {
    if (i > 0) f->AddString(", ");
    ArgumentValueAt(i)->PrintTo(f);
  }
}

void LoadLocalInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s @%d", local().name().ToCString(), local().index().value());
}

void StoreLocalInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s @%d, ", local().name().ToCString(), local().index().value());
  value()->PrintTo(f);
}

void NativeCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s", native_name().ToCString());
}

void GuardFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s %s, ", String::Handle(field().name()).ToCString(),
            field().GuardedPropertiesAsCString());
  value()->PrintTo(f);
}

void StoreFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  instance()->PrintTo(f);
  f->Printf(" . %s = ", slot().Name());
  value()->PrintTo(f);
  if (slot().representation() != kTagged) {
    f->Printf(" <%s>", RepresentationUtils::ToCString(slot().representation()));
  }

  // Here, we just print the value of the enum field. We would prefer to get
  // the final decision on whether a store barrier will be emitted by calling
  // ShouldEmitStoreBarrier(), but that can change parts of the flow graph.
  if (emit_store_barrier_ == kNoStoreBarrier) {
    f->AddString(", NoStoreBarrier");
  }
  if (stores_inner_pointer() == InnerPointerAccess::kMayBeInnerPointer) {
    f->AddString(", MayStoreInnerPointer");
  }
}

void IfThenElseInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  condition()->PrintOperandsTo(f);
  f->Printf(" ? %" Pd " : %" Pd, if_true_, if_false_);
}

void LoadStaticFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s", String::Handle(field().name()).ToCString());
  if (calls_initializer()) {
    f->AddString(", CallsInitializer");
  }
}

void StoreStaticFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s, ", String::Handle(field().name()).ToCString());
  value()->PrintTo(f);
}

void InstanceOfInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  value()->PrintTo(f);
  f->Printf(" IS %s,", type().NameCString());
  f->AddString(" instantiator_type_args(");
  instantiator_type_arguments()->PrintTo(f);
  f->AddString("), function_type_args(");
  function_type_arguments()->PrintTo(f);
  f->AddString(")");
}

void RelationalOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s, ", Token::Str(kind()));
  left()->PrintTo(f);
  f->AddString(", ");
  right()->PrintTo(f);
}

void AllocationInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Definition::PrintOperandsTo(f);
  if (Identity().IsNotAliased()) {
    if (InputCount() > 0) {
      f->AddString(", ");
    }
    f->AddString("<not-aliased>");
  }
}

void AllocateObjectInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("cls=%s", cls().ScrubbedNameCString());
  if (InputCount() > 0 || Identity().IsNotAliased()) {
    f->AddString(", ");
  }
  AllocationInstr::PrintOperandsTo(f);
}

void MaterializeObjectInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s", cls_.ScrubbedNameCString());
  for (intptr_t i = 0; i < InputCount(); i++) {
    f->AddString(", ");
    f->Printf("%s: ", slots_[i]->Name());
    InputAt(i)->PrintTo(f);
  }
}

void LoadFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  instance()->PrintTo(f);
  f->Printf(" . %s%s", slot().Name(), IsImmutableLoad() ? " {final}" : "");
  if (calls_initializer()) {
    f->AddString(", CallsInitializer");
  }
  if (loads_inner_pointer() == InnerPointerAccess::kMayBeInnerPointer) {
    f->AddString(", MayLoadInnerPointer");
  }
}

void LoadUntaggedInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  object()->PrintTo(f);
  f->Printf(", %" Pd, offset());
}

void CalculateElementAddressInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Definition::PrintOperandsTo(f);
  f->Printf(", index_scale=%" Pd "", index_scale());
}

void InstantiateTypeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  const String& type_name = String::Handle(type().Name());
  f->Printf("%s,", type_name.ToCString());
  f->AddString(" instantiator_type_args(");
  instantiator_type_arguments()->PrintTo(f);
  f->AddString("), function_type_args(");
  function_type_arguments()->PrintTo(f);
  f->AddString(")");
}

void InstantiateTypeArgumentsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  type_arguments()->PrintTo(f);
  f->AddString(", instantiator_type_args(");
  instantiator_type_arguments()->PrintTo(f);
  f->AddString("), function_type_args(");
  function_type_arguments()->PrintTo(f);
  f->Printf(")");
  if (!instantiator_class().IsNull()) {
    f->Printf(", instantiator_class(%s)", instantiator_class().ToCString());
  }
}

void AllocateContextInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("num_variables=%" Pd "", num_context_variables());
  if (InputCount() > 0 || Identity().IsNotAliased()) {
    f->AddString(", ");
  }
  TemplateAllocation::PrintOperandsTo(f);
}

void AllocateUninitializedContextInstr::PrintOperandsTo(
    BaseTextBuffer* f) const {
  f->Printf("num_variables=%" Pd "", num_context_variables());
  if (InputCount() > 0 || Identity().IsNotAliased()) {
    f->AddString(", ");
  }
  TemplateAllocation::PrintOperandsTo(f);
}

void TruncDivModInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Definition::PrintOperandsTo(f);
}

void ExtractNthOutputInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("Extract %" Pd " from ", index());
  Definition::PrintOperandsTo(f);
}

void UnboxLaneInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Definition::PrintOperandsTo(f);
  f->Printf(", lane %" Pd, lane());
}

void BoxLanesInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Definition::PrintOperandsTo(f);
}

void UnaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s, ", Token::Str(op_kind()));
  value()->PrintTo(f);
}

void BinaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s", Token::Str(op_kind()));
  if (is_truncating()) {
    f->AddString(" [tr]");
  } else if (!can_overflow()) {
    f->AddString(" [-o]");
  }
  f->AddString(", ");
  left()->PrintTo(f);
  f->AddString(", ");
  right()->PrintTo(f);
}

void BinaryDoubleOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s, ", Token::Str(op_kind()));
  left()->PrintTo(f);
  f->AddString(", ");
  right()->PrintTo(f);
}

void DoubleTestOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  switch (op_kind()) {
    case MethodRecognizer::kDouble_getIsNaN:
      f->AddString("IsNaN ");
      break;
    case MethodRecognizer::kDouble_getIsInfinite:
      f->AddString("IsInfinite ");
      break;
    case MethodRecognizer::kDouble_getIsNegative:
      f->AddString("IsNegative ");
      break;
    default:
      UNREACHABLE();
  }
  value()->PrintTo(f);
}

static const char* const simd_op_kind_string[] = {
#define CASE(Arity, Mask, Name, ...) #Name,
    SIMD_OP_LIST(CASE, CASE)
#undef CASE
};

void SimdOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s", simd_op_kind_string[kind()]);
  if (HasMask()) {
    f->Printf(", mask = %" Pd "", mask());
  }
  for (intptr_t i = 0; i < InputCount(); i++) {
    f->AddString(", ");
    InputAt(i)->PrintTo(f);
  }
}

void UnaryDoubleOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s, ", Token::Str(op_kind()));
  value()->PrintTo(f);
}

void LoadClassIdInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  if (!input_can_be_smi_) {
    f->AddString("<non-smi> ");
  }
  object()->PrintTo(f);
}

void CheckClassIdInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  value()->PrintTo(f);

  const Class& cls = Class::Handle(
      IsolateGroup::Current()->class_table()->At(cids().cid_start));
  const String& name = String::Handle(cls.ScrubbedName());
  if (cids().IsSingleCid()) {
    f->Printf(", %s", name.ToCString());
  } else {
    const Class& cls2 = Class::Handle(
        IsolateGroup::Current()->class_table()->At(cids().cid_end));
    const String& name2 = String::Handle(cls2.ScrubbedName());
    f->Printf(", cid %" Pd "-%" Pd " %s-%s", cids().cid_start, cids().cid_end,
              name.ToCString(), name2.ToCString());
  }
}

void HashIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  if (smi_) {
    f->AddString("smi ");
  }

  value()->PrintTo(f);
}

void CheckClassInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  value()->PrintTo(f);
  PrintCidsHelper(f, cids_, FlowGraphPrinter::kPrintAll);
  if (IsNullCheck()) {
    f->AddString(" nullcheck");
  }
}

void CheckConditionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  condition()->PrintOperandsTo(f);
}

void InvokeMathCFunctionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s, ", MethodRecognizer::KindToCString(recognized_kind_));
  Definition::PrintOperandsTo(f);
}

void GraphEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
  f->Printf("B%" Pd "[graph]:%" Pd, block_id(), GetDeoptId());
}

void JoinEntryInstr::PrintTo(BaseTextBuffer* f) const {
  if (try_index() != kInvalidTryIndex) {
    f->Printf("B%" Pd "[join try_idx %" Pd "]:%" Pd " pred(", block_id(),
              try_index(), GetDeoptId());
  } else {
    f->Printf("B%" Pd "[join]:%" Pd " pred(", block_id(), GetDeoptId());
  }
  for (intptr_t i = 0; i < predecessors_.length(); ++i) {
    if (i > 0) f->AddString(", ");
    f->Printf("B%" Pd, predecessors_[i]->block_id());
  }
  f->AddString(")");
  if (phis_ != nullptr) {
    f->AddString(" {");
    for (intptr_t i = 0; i < phis_->length(); ++i) {
      if ((*phis_)[i] == nullptr) continue;
      f->AddString("\n      ");
      (*phis_)[i]->PrintTo(f);
    }
    f->AddString("\n}");
  }
  if (HasParallelMove()) {
    f->AddString(" ");
    parallel_move()->PrintTo(f);
  }
}

void IndirectEntryInstr::PrintTo(BaseTextBuffer* f) const {
  f->Printf("B%" Pd "[join indirect", block_id());
  if (try_index() != kInvalidTryIndex) {
    f->Printf(" try_idx %" Pd, try_index());
  }
  f->Printf("]:%" Pd " pred(", GetDeoptId());
  for (intptr_t i = 0; i < predecessors_.length(); ++i) {
    if (i > 0) f->AddString(", ");
    f->Printf("B%" Pd, predecessors_[i]->block_id());
  }
  f->AddString(")");
  if (phis_ != nullptr) {
    f->AddString(" {");
    for (intptr_t i = 0; i < phis_->length(); ++i) {
      if ((*phis_)[i] == nullptr) continue;
      f->AddString("\n      ");
      (*phis_)[i]->PrintTo(f);
    }
    f->AddString("\n}");
  }
  if (HasParallelMove()) {
    f->AddString(" ");
    parallel_move()->PrintTo(f);
  }
}

void PhiInstr::PrintTo(BaseTextBuffer* f) const {
  f->Printf("v%" Pd " <- phi(", ssa_temp_index());
  for (intptr_t i = 0; i < inputs_.length(); ++i) {
    if (inputs_[i] != nullptr) inputs_[i]->PrintTo(f);
    if (i < inputs_.length() - 1) f->AddString(", ");
  }
  f->AddString(")");
  f->AddString(is_alive() ? " alive" : " dead");
  if (range_ != nullptr) {
    f->AddString(" ");
    range_->PrintTo(f);
  }

  if (representation() != kNoRepresentation && representation() != kTagged) {
    f->Printf(" %s", RepresentationUtils::ToCString(representation()));
  }

  if (HasType()) {
    f->Printf(" %s", TypeAsCString());
  }
}

void UnboxIntegerInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  if (value_mode() == ValueMode::kCheckType) {
    f->AddString("[check-type], ");
  }
  Definition::PrintOperandsTo(f);
}

void IntConverterInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s->%s, ", RepresentationUtils::ToCString(from()),
            RepresentationUtils::ToCString(to()));
  Definition::PrintOperandsTo(f);
}

void BitCastInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Definition::PrintOperandsTo(f);
  f->Printf(" (%s -> %s)", RepresentationUtils::ToCString(from()),
            RepresentationUtils::ToCString(to()));
}

void ParameterInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%" Pd " @%s", env_index(), location().ToCString());
}

void CheckStackOverflowInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("stack=%" Pd ", loop=%" Pd, stack_depth(), loop_depth());
}

void TargetEntryInstr::PrintTo(BaseTextBuffer* f) const {
  if (try_index() != kInvalidTryIndex) {
    f->Printf("B%" Pd "[target try_idx %" Pd "]:%" Pd, block_id(), try_index(),
              GetDeoptId());
  } else {
    f->Printf("B%" Pd "[target]:%" Pd, block_id(), GetDeoptId());
  }
  if (HasParallelMove()) {
    f->AddString(" ");
    parallel_move()->PrintTo(f);
  }
}

void BlockEntryWithInitialDefs::PrintTo(BaseTextBuffer* f) const {
  PrintBlockHeaderTo(f);
  PrintInitialDefinitionsTo(f, [](BaseTextBuffer* f) {});
}

void BlockEntryWithInitialDefs::PrintInitialDefinitionsTo(
    BaseTextBuffer* f,
    std::function<void(BaseTextBuffer* f)> callback) const {
  const GrowableArray<Definition*>& defns = initial_definitions_;
  if (defns.length() > 0) {
    f->AddString(" {");
    for (intptr_t i = 0; i < defns.length(); ++i) {
      Definition* const def = defns[i];
      // Skip constants which are not used in the graph.
      if (!ShouldPrintInstruction(def)) {
        continue;
      }
      f->AddString("\n      ");
      def->PrintTo(f);
      callback(f);
    }
    f->AddString("\n}");
  }
}

void OsrEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
  f->Printf("B%" Pd "[osr entry]:%" Pd " stack_depth=%" Pd, block_id(),
            GetDeoptId(), stack_depth());
  if (HasParallelMove()) {
    f->AddString("\n");
    parallel_move()->PrintTo(f);
  }
}

void FunctionEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
  f->Printf("B%" Pd "[function entry]:%" Pd, block_id(), GetDeoptId());
  if (HasParallelMove()) {
    f->AddString("\n");
    parallel_move()->PrintTo(f);
  }
}

void NativeEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
  f->Printf("B%" Pd "[native function entry]:%" Pd, block_id(), GetDeoptId());
  if (HasParallelMove()) {
    f->AddString("\n");
    parallel_move()->PrintTo(f);
  }
}

void FfiCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->AddString(" pointer=");
  InputAt(TargetAddressIndex())->PrintTo(f);
  if (marshaller_.ReturnsCompound()) {
    f->AddString(", compound_return_typed_data=");
    InputAt(CompoundReturnTypedDataIndex())->PrintTo(f);
  }
  intptr_t def_index = 0;
  for (intptr_t arg_index = 0; arg_index < marshaller_.num_args();
       arg_index++) {
    const auto& arg_location = marshaller_.Location(arg_index);
    const bool is_compound = arg_location.container_type().IsCompound();
    const intptr_t num_defs = marshaller_.NumDefinitions(arg_index);
    f->AddString(", ");
    if (is_compound) f->AddString("(");
    for (intptr_t i = 0; i < num_defs; i++) {
      InputAt(def_index)->PrintTo(f);
      if ((i + 1) < num_defs) f->AddString(", ");
      def_index++;
    }
    if (is_compound) f->AddString(")");
    f->AddString(" (@");
    arg_location.PrintTo(f);
    f->AddString(")");
  }
}

void LeafRuntimeCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->AddString("target_address=");
  InputAt(TargetAddressIndex())->PrintTo(f);
  for (intptr_t i = 0, n = argument_representations_.length(); i < n; ++i) {
    f->AddString(", ");
    InputAt(i)->PrintTo(f);
  }
}

void NativeReturnInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  if (marshaller_.NumReturnDefinitions() == 1) {
    InputAt(0)->PrintTo(f);
  } else {
    ASSERT_EQUAL(marshaller_.NumReturnDefinitions(), 2);
    f->AddString("(");
    InputAt(0)->PrintTo(f);
    f->AddString(", ");
    InputAt(1)->PrintTo(f);
    f->AddString(")");
  }

  f->AddString(" (@");
  marshaller_.Location(compiler::ffi::kResultIndex).PrintTo(f);
  f->AddString(")");
}

void NativeParameterInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  // Where the calling convention puts it.
  marshaller_.Location(marshaller_.ArgumentIndex(def_index_)).PrintTo(f);
  f->AddString(" at ");
  // Where the arguments are when pushed on the stack.
  marshaller_.NativeLocationOfNativeParameter(def_index_).PrintTo(f);
}

void TryEntryInstr::PrintTo(BaseTextBuffer* f) const {
  f->Printf("B%" Pd "[try_entry try_idx %" Pd "]:%" Pd " try_body:[B%" Pd
            "] catches:[B%" Pd "] pred(",
            block_id(), try_index(), GetDeoptId(), try_body_->block_id(),
            catch_target_->block_id());

  for (intptr_t i = 0; i < PredecessorCount(); ++i) {
    if (i > 0) f->AddString(", ");
    f->Printf("B%" Pd, PredecessorAt(i)->block_id());
  }
  f->AddString(")");
  if (phis() != nullptr) {
    f->AddString(" {");
    for (intptr_t i = 0; i < phis()->length(); ++i) {
      if ((*phis())[i] == nullptr) continue;
      f->AddString("\n      ");
      (*phis())[i]->PrintTo(f);
    }
    f->AddString("\n}");
  }

  if (HasParallelMove()) {
    f->AddString(" ");
    parallel_move()->PrintTo(f);
  }
}

void CatchBlockEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
  if (try_index() != kInvalidTryIndex) {
    f->Printf("B%" Pd "[catch catch_try_index %" Pd " try_idx %" Pd "]",
              block_id(), catch_try_index(), try_index());
  } else {
    f->Printf("B%" Pd "[catch catch_try_index %" Pd "]", block_id(),
              catch_try_index());
  }
  if (HasParallelMove()) {
    f->AddString("\n");
    parallel_move()->PrintTo(f);
  }
}

void LoadIndexedUnsafeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s[", RegisterNames::RegisterName(base_reg()));
  index()->PrintTo(f);
  f->Printf(" + %" Pd "]", offset());
}

void StoreIndexedUnsafeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s[", RegisterNames::RegisterName(base_reg()));
  index()->PrintTo(f);
  f->Printf(" + %" Pd "], ", offset());
  value()->PrintTo(f);
}

void LoadIndexedInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  auto& cls =
      Class::Handle(IsolateGroup::Current()->class_table()->At(class_id()));
  if (!cls.IsNull()) {
    f->Printf("[%s] ", cls.ScrubbedNameCString());
  } else {
    f->Printf("[cid %" Pd "] ", class_id());
  }
  Instruction::PrintOperandsTo(f);
}

void StoreIndexedInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  auto& cls =
      Class::Handle(IsolateGroup::Current()->class_table()->At(class_id()));
  if (!cls.IsNull()) {
    f->Printf("[%s] ", cls.ScrubbedNameCString());
  } else {
    f->Printf("[cid %" Pd "] ", class_id());
  }
  Instruction::PrintOperandsTo(f);
  if (!ShouldEmitStoreBarrier()) {
    f->AddString(", NoStoreBarrier");
  }
}

void MemoryCopyInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Instruction::PrintOperandsTo(f);
  auto& cls =
      Class::Handle(IsolateGroup::Current()->class_table()->At(dest_cid_));
  if (!cls.IsNull()) {
    f->Printf(", dest_cid=%s (%d)", cls.ScrubbedNameCString(), dest_cid_);
  } else {
    f->Printf(", dest_cid=%d", dest_cid_);
  }
  if (dest()->definition()->representation() == kUntagged) {
    f->Printf(" [untagged]");
  }
  cls = IsolateGroup::Current()->class_table()->At(src_cid_);
  if (!cls.IsNull()) {
    f->Printf(", src_cid=%s (%d)", cls.ScrubbedNameCString(), src_cid_);
  } else {
    f->Printf(", src_cid=%d", src_cid_);
  }
  if (src()->definition()->representation() == kUntagged) {
    f->Printf(" [untagged]");
  }
  if (element_size() != 1) {
    f->Printf(", element_size=%" Pd "", element_size());
  }
  if (unboxed_inputs()) {
    f->AddString(", unboxed_inputs");
  }
  if (can_overlap()) {
    f->AddString(", can_overlap");
  }
}

void TailCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  const char* name = "<unknown code>";
  if (code_.IsStubCode()) {
    name = StubCode::NameOfStub(code_.EntryPoint());
  } else {
    const Object& owner = Object::Handle(code_.owner());
    if (owner.IsFunction()) {
      name = Function::Handle(Function::RawCast(owner.ptr()))
                 .ToFullyQualifiedCString();
    }
  }
  f->Printf("%s(", name);
  InputAt(0)->PrintTo(f);
  f->AddString(")");
}

void Call1ArgStubInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  const char* name = "";
  switch (stub_id_) {
    case StubId::kCloneSuspendState:
      name = "CloneSuspendState";
      break;
    case StubId::kInitAsync:
      name = "InitAsync";
      break;
    case StubId::kInitAsyncStar:
      name = "InitAsyncStar";
      break;
    case StubId::kInitSyncStar:
      name = "InitSyncStar";
      break;
    case StubId::kFfiAsyncCallbackSend:
      name = "FfiAsyncCallbackSend";
      break;
  }
  f->Printf("%s(", name);
  operand()->PrintTo(f);
  f->AddString(")");
}

void SuspendInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  const char* name = "";
  switch (stub_id_) {
    case StubId::kAwait:
      name = "Await";
      break;
    case StubId::kAwaitWithTypeCheck:
      name = "AwaitWithTypeCheck";
      break;
    case StubId::kYieldAsyncStar:
      name = "YieldAsyncStar";
      break;
    case StubId::kSuspendSyncStarAtStart:
      name = "SuspendSyncStarAtStart";
      break;
    case StubId::kSuspendSyncStarAtYield:
      name = "SuspendSyncStarAtYield";
      break;
  }
  f->Printf("%s(", name);
  Definition::PrintOperandsTo(f);
  f->AddString(")");
}

void MoveArgumentInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  f->Printf("%s <- ", location().ToCString());
  value()->PrintTo(f);
}

void GenericCheckBoundInstr::PrintOperandsTo(BaseTextBuffer* f) const {
  Definition::PrintOperandsTo(f);
  if (IsPhantom()) {
    f->AddString(", phantom");
  }
}

void GotoInstr::PrintTo(BaseTextBuffer* f) const {
  if (HasParallelMove()) {
    parallel_move()->PrintTo(f);
    f->AddString(" ");
  }
  if (GetDeoptId() != DeoptId::kNone) {
    f->Printf("goto:%" Pd " B%" Pd "", GetDeoptId(), successor()->block_id());
  } else {
    f->Printf("goto: B%" Pd "", successor()->block_id());
  }
}

void IndirectGotoInstr::PrintTo(BaseTextBuffer* f) const {
  if (GetDeoptId() != DeoptId::kNone) {
    f->Printf("igoto:%" Pd "(", GetDeoptId());
  } else {
    f->AddString("igoto:(");
  }
  InputAt(0)->PrintTo(f);
  f->AddString(")");
}

void BranchInstr::PrintTo(BaseTextBuffer* f) const {
  f->Printf("%s ", DebugName());
  f->AddString("if ");
  condition()->PrintTo(f);

  f->Printf(" goto (%" Pd ", %" Pd ")", true_successor()->block_id(),
            false_successor()->block_id());
}

void ParallelMoveInstr::PrintTo(BaseTextBuffer* f) const {
  f->Printf("%s ", DebugName());
  for (intptr_t i = 0; i < moves_.length(); i++) {
    if (i != 0) f->AddString(", ");
    moves_[i]->dest().PrintTo(f);
    f->AddString(" <- ");
    moves_[i]->src().PrintTo(f);
  }
}

void Utf8ScanInstr::PrintTo(BaseTextBuffer* f) const {
  Definition::PrintTo(f);
  f->Printf(" [%s]", scan_flags_field_.Name());
}

void Environment::PrintTo(BaseTextBuffer* f) const {
  f->AddString(" env={ ");
  int arg_count = 0;
  for (intptr_t i = 0; i < values_.length(); ++i) {
    if (i > 0) f->AddString(", ");
    if (values_[i]->definition()->IsMoveArgument()) {
      f->Printf("a%d", arg_count++);
    } else {
      values_[i]->PrintTo(f);
    }
    if ((locations_ != nullptr) && !locations_[i].IsInvalid()) {
      f->AddString(" [");
      locations_[i].PrintTo(f);
      f->AddString("]");
    }
  }
  f->AddString(" }");
  if (outer_ != nullptr) outer_->PrintTo(f);
}

const char* Environment::ToCString() const {
  char buffer[1024];
  BufferFormatter bf(buffer, 1024);
  PrintTo(&bf);
  return Thread::Current()->zone()->MakeCopyOfString(buffer);
}

#else  // defined(INCLUDE_IL_PRINTER)

const char* Instruction::ToCString() const {
  return DebugName();
}

void FlowGraphPrinter::PrintOneInstruction(Instruction* instr,
                                           bool print_locations) {
  UNREACHABLE();
}

void FlowGraphPrinter::PrintTypeCheck(const ParsedFunction& parsed_function,
                                      TokenPosition token_pos,
                                      Value* value,
                                      const AbstractType& dst_type,
                                      const String& dst_name,
                                      bool eliminated) {
  UNREACHABLE();
}

void FlowGraphPrinter::PrintBlock(BlockEntryInstr* block,
                                  bool print_locations) {
  UNREACHABLE();
}

void FlowGraphPrinter::PrintGraph(const char* phase, FlowGraph* flow_graph) {
  UNREACHABLE();
}

void FlowGraphPrinter::PrintICData(const ICData& ic_data,
                                   intptr_t num_checks_to_print) {
  UNREACHABLE();
}

bool FlowGraphPrinter::ShouldPrint(
    const Function& function,
    uint8_t** compiler_pass_filter /* = nullptr */) {
  return false;
}

#endif  // defined(INCLUDE_IL_PRINTER)

}  // namespace dart
