mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-19 03:45:53 +00:00

This patch adds a new ReadAdvance definition named ReadInt2Fpu. ReadInt2Fpu allows x86 scheduling models to accurately describe delays caused by data transfers from the integer unit to the floating point unit. ReadInt2Fpu currently defaults to a delay of zero cycles (i.e. no delay) for all x86 models excluding BtVer2. That means, this patch is only a functional change for the Jaguar cpu model only. Tablegen definitions for instructions (V)PINSR* have been updated to account for the new ReadInt2Fpu. That read is mapped to the the GPR input operand. On Jaguar, int-to-fpu transfers are modeled as a +6cy delay. Before this patch, that extra delay was added to the opcode latency. In practice, the insert opcode only executes for 1cy. Most of the actual latency is actually contributed by the so-called operand-latency. According to the AMD SOG for family 16h, (V)PINSR* latency is defined by expression f+1, where f is defined as a forwarding delay from the integer unit to the fpu. When printing instruction latency from MCA (see InstructionInfoView.cpp) and LLC (only when flag -print-schedule is speified), we now need to account for any extra forwarding delays. We do this by checking if scheduling classes declare any negative ReadAdvance entries. Quoting a code comment in TargetSchedule.td: "A negative advance effectively increases latency, which may be used for cross-domain stalls". When computing the instruction latency for the purpose of our scheduling tests, we now add any extra delay to the formula. This avoids regressing existing codegen and mca schedule tests. It comes with the cost of an extra (but very simple) hook in MCSchedModel. Differential Revision: https://reviews.llvm.org/D57056 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351965 91177308-0d34-0410-b5e6-96231b3b80d8
92 lines
3.1 KiB
C++
92 lines
3.1 KiB
C++
//===--------------------- InstructionInfoView.cpp --------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
/// \file
|
|
///
|
|
/// This file implements the InstructionInfoView API.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Views/InstructionInfoView.h"
|
|
|
|
namespace llvm {
|
|
namespace mca {
|
|
|
|
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;
|
|
}
|
|
} // namespace mca.
|
|
} // namespace llvm
|