Exemple #1
0
void SchedulerStatistics::printSchedulerUsage(raw_ostream &OS) const {
  std::string Buffer;
  raw_string_ostream TempStream(Buffer);
  TempStream << "\n\nScheduler's queue usage:\n";
  // Early exit if no buffered resources were consumed.
  if (BufferedResources.empty()) {
    TempStream << "No scheduler resources used.\n";
    TempStream.flush();
    OS << Buffer;
    return;
  }

  for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
    const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
    if (ProcResource.BufferSize <= 0)
      continue;

    const BufferUsage &BU = BufferedResources.lookup(I);
    TempStream << ProcResource.Name << ",  " << BU.MaxUsedSlots << '/'
               << ProcResource.BufferSize << '\n';
  }

  TempStream.flush();
  OS << Buffer;
}
Exemple #2
0
void DispatchStatistics::printDispatchHistogram(raw_ostream &OS) const {
  std::string Buffer;
  raw_string_ostream TempStream(Buffer);
  TempStream << "\n\nDispatch Logic - "
             << "number of cycles where we saw N micro opcodes dispatched:\n";
  TempStream << "[# dispatched], [# cycles]\n";
  for (const std::pair<unsigned, unsigned> &Entry : DispatchGroupSizePerCycle) {
    double Percentage = ((double)Entry.second / NumCycles) * 100.0;
    TempStream << " " << Entry.first << ",              " << Entry.second
               << "  (" << format("%.1f", floor((Percentage * 10) + 0.5) / 10)
               << "%)\n";
  }

  TempStream.flush();
  OS << Buffer;
}
Exemple #3
0
void SchedulerStatistics::printSchedulerStatistics(
    llvm::raw_ostream &OS) const {
  std::string Buffer;
  raw_string_ostream TempStream(Buffer);
  TempStream << "\n\nSchedulers - number of cycles where we saw N instructions "
                "issued:\n";
  TempStream << "[# issued], [# cycles]\n";
  for (const std::pair<unsigned, unsigned> &Entry : IssuedPerCycle) {
    TempStream << " " << Entry.first << ",          " << Entry.second << "  ("
               << format("%.1f", ((double)Entry.second / NumCycles) * 100)
               << "%)\n";
  }

  TempStream.flush();
  OS << Buffer;
}
void RegisterFileStatistics::printView(raw_ostream &OS) const {
  std::string Buffer;
  raw_string_ostream TempStream(Buffer);

  TempStream << "\n\nRegister File statistics:";
  const RegisterFileUsage &GlobalUsage = PRFUsage[0];
  TempStream << "\nTotal number of mappings created:    "
             << GlobalUsage.TotalMappings;
  TempStream << "\nMax number of mappings used:         "
             << GlobalUsage.MaxUsedMappings << '\n';

  for (unsigned I = 1, E = PRFUsage.size(); I < E; ++I) {
    const RegisterFileUsage &RFU = PRFUsage[I];
    // Obtain the register file descriptor from the scheduling model.
    assert(STI.getSchedModel().hasExtraProcessorInfo() &&
           "Unable to find register file info!");
    const MCExtraProcessorInfo &PI =
        STI.getSchedModel().getExtraProcessorInfo();
    assert(I <= PI.NumRegisterFiles && "Unexpected register file index!");
    const MCRegisterFileDesc &RFDesc = PI.RegisterFiles[I];
    // Skip invalid register files.
    if (!RFDesc.NumPhysRegs)
      continue;

    TempStream << "\n*  Register File #" << I;
    TempStream << " -- " << StringRef(RFDesc.Name) << ':';
    TempStream << "\n   Number of physical registers:     ";
    if (!RFDesc.NumPhysRegs)
      TempStream << "unbounded";
    else
      TempStream << RFDesc.NumPhysRegs;
    TempStream << "\n   Total number of mappings created: "
               << RFU.TotalMappings;
    TempStream << "\n   Max number of mappings used:      "
               << RFU.MaxUsedMappings << '\n';
    const MoveEliminationInfo &MEI = MoveElimInfo[I];

    if (MEI.TotalMoveEliminationCandidates) {
      TempStream << "   Number of optimizable moves:      "
                 << MEI.TotalMoveEliminationCandidates;
      double EliminatedMovProportion = (double)MEI.TotalMovesEliminated /
                                       MEI.TotalMoveEliminationCandidates *
                                       100.0;
      double ZeroMovProportion = (double)MEI.TotalMovesThatPropagateZero /
                                 MEI.TotalMoveEliminationCandidates * 100.0;
      TempStream << "\n   Number of moves eliminated:       "
                 << MEI.TotalMovesEliminated << "  "
                 << format("(%.1f%%)",
                           floor((EliminatedMovProportion * 10) + 0.5) / 10);
      TempStream << "\n   Number of zero moves:             "
                 << MEI.TotalMovesThatPropagateZero << "  "
                 << format("(%.1f%%)",
                           floor((ZeroMovProportion * 10) + 0.5) / 10);
      TempStream << "\n   Max moves eliminated per cycle:   "
                 << MEI.MaxMovesEliminatedPerCycle << '\n';
    }
  }

  TempStream.flush();
  OS << Buffer;
}
void InstructionInfoView::printView(raw_ostream &OS) const {
  std::string Buffer;
  raw_string_ostream TempStream(Buffer);
  const MCSchedModel &SM = STI.getSchedModel();

  std::string Instruction;
  raw_string_ostream InstrStream(Instruction);

  TempStream << "\n\nInstruction Info:\n";
  TempStream << "[1]: #uOps\n[2]: Latency\n[3]: RThroughput\n"
             << "[4]: MayLoad\n[5]: MayStore\n[6]: HasSideEffects (U)\n\n";

  TempStream << "[1]    [2]    [3]    [4]    [5]    [6]    Instructions:\n";
  for (const MCInst &Inst : Source) {
    const MCInstrDesc &MCDesc = MCII.get(Inst.getOpcode());

    // Obtain the scheduling class information from the instruction.
    unsigned SchedClassID = MCDesc.getSchedClass();
    unsigned CPUID = SM.getProcessorID();

    // Try to solve variant scheduling classes.
    while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant())
      SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, CPUID);

    const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
    unsigned NumMicroOpcodes = SCDesc.NumMicroOps;
    unsigned Latency = MCSchedModel::computeInstrLatency(STI, SCDesc);
    // Add extra latency due to delays in the forwarding data paths.
    Latency += MCSchedModel::getForwardingDelayCycles(
        STI.getReadAdvanceEntries(SCDesc));
    Optional<double> RThroughput =
        MCSchedModel::getReciprocalThroughput(STI, SCDesc);

    TempStream << ' ' << NumMicroOpcodes << "    ";
    if (NumMicroOpcodes < 10)
      TempStream << "  ";
    else if (NumMicroOpcodes < 100)
      TempStream << ' ';
    TempStream << Latency << "   ";
    if (Latency < 10)
      TempStream << "  ";
    else if (Latency < 100)
      TempStream << ' ';

    if (RThroughput.hasValue()) {
      double RT = RThroughput.getValue();
      TempStream << format("%.2f", RT) << ' ';
      if (RT < 10.0)
        TempStream << "  ";
      else if (RT < 100.0)
        TempStream << ' ';
    } else {
      TempStream << " -     ";
    }
    TempStream << (MCDesc.mayLoad() ? " *     " : "       ");
    TempStream << (MCDesc.mayStore() ? " *     " : "       ");
    TempStream << (MCDesc.hasUnmodeledSideEffects() ? " U " : "   ");

    MCIP.printInst(&Inst, InstrStream, "", STI);
    InstrStream.flush();

    // Consume any tabs or spaces at the beginning of the string.
    StringRef Str(Instruction);
    Str = Str.ltrim();
    TempStream << "    " << Str << '\n';
    Instruction = "";
  }

  TempStream.flush();
  OS << Buffer;
}