[llvm] r336543 - [llvm-mca] report an error if the assembly sequence contains an unsupported instruction.
Andrea Di Biagio via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 9 05:30:55 PDT 2018
Author: adibiagio
Date: Mon Jul 9 05:30:55 2018
New Revision: 336543
URL: http://llvm.org/viewvc/llvm-project?rev=336543&view=rev
Log:
[llvm-mca] report an error if the assembly sequence contains an unsupported instruction.
This is a short-term fix for PR38093.
For now, we llvm::report_fatal_error if the instruction builder finds an
unsupported instruction in the instruction stream.
We need to revisit this fix once we start addressing PR38101.
Essentially, we need a better framework for error handling.
Added:
llvm/trunk/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s
Modified:
llvm/trunk/tools/llvm-mca/InstrBuilder.cpp
llvm/trunk/tools/llvm-mca/InstrBuilder.h
llvm/trunk/tools/llvm-mca/llvm-mca.cpp
Added: llvm/trunk/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s?rev=336543&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s (added)
+++ llvm/trunk/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s Mon Jul 9 05:30:55 2018
@@ -0,0 +1,6 @@
+# RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 %s 2>&1 | FileCheck %s
+
+bzhi %eax, %ebx, %ecx
+
+# CHECK: error: found an unsupported instruction in the input assembly sequence.
+# CHECK-NEXT: note: instruction: bzhil %eax, %ebx, %ecx
Modified: llvm/trunk/tools/llvm-mca/InstrBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/InstrBuilder.cpp?rev=336543&r1=336542&r2=336543&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/InstrBuilder.cpp (original)
+++ llvm/trunk/tools/llvm-mca/InstrBuilder.cpp Mon Jul 9 05:30:55 2018
@@ -17,8 +17,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
#define DEBUG_TYPE "llvm-mca"
@@ -155,10 +155,12 @@ static void computeMaxLatency(InstrDesc
ID.MaxLatency = Latency < 0 ? 100U : static_cast<unsigned>(Latency);
}
-static void populateWrites(InstrDesc &ID, const MCInst &MCI,
- const MCInstrDesc &MCDesc,
- const MCSchedClassDesc &SCDesc,
- const MCSubtargetInfo &STI) {
+void InstrBuilder::populateWrites(InstrDesc &ID, const MCInst &MCI,
+ unsigned SchedClassID) {
+ const MCInstrDesc &MCDesc = MCII.get(MCI.getOpcode());
+ const MCSchedModel &SM = STI.getSchedModel();
+ const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
+
// These are for now the (strong) assumptions made by this algorithm:
// * The number of explicit and implicit register definitions in a MCInst
// matches the number of explicit and implicit definitions according to
@@ -196,8 +198,8 @@ static void populateWrites(InstrDesc &ID
const MCWriteLatencyEntry &WLE =
*STI.getWriteLatencyEntry(&SCDesc, CurrentDef);
// Conservatively default to MaxLatency.
- Write.Latency = WLE.Cycles < 0 ? ID.MaxLatency
- : static_cast<unsigned>(WLE.Cycles);
+ Write.Latency =
+ WLE.Cycles < 0 ? ID.MaxLatency : static_cast<unsigned>(WLE.Cycles);
Write.SClassOrWriteResourceID = WLE.WriteResourceID;
} else {
// Assign a default latency for this write.
@@ -226,8 +228,8 @@ static void populateWrites(InstrDesc &ID
const MCWriteLatencyEntry &WLE =
*STI.getWriteLatencyEntry(&SCDesc, Index);
// Conservatively default to MaxLatency.
- Write.Latency = WLE.Cycles < 0 ? ID.MaxLatency
- : static_cast<unsigned>(WLE.Cycles);
+ Write.Latency =
+ WLE.Cycles < 0 ? ID.MaxLatency : static_cast<unsigned>(WLE.Cycles);
Write.SClassOrWriteResourceID = WLE.WriteResourceID;
} else {
// Assign a default latency for this write.
@@ -262,14 +264,13 @@ static void populateWrites(InstrDesc &ID
}
}
-static void populateReads(InstrDesc &ID, const MCInst &MCI,
- const MCInstrDesc &MCDesc,
- const MCSchedClassDesc &SCDesc,
- const MCSubtargetInfo &STI) {
- unsigned SchedClassID = MCDesc.getSchedClass();
- unsigned i = 0;
+void InstrBuilder::populateReads(InstrDesc &ID, const MCInst &MCI,
+ unsigned SchedClassID) {
+ const MCInstrDesc &MCDesc = MCII.get(MCI.getOpcode());
unsigned NumExplicitDefs = MCDesc.getNumDefs();
+
// Skip explicit definitions.
+ unsigned i = 0;
for (; i < MCI.getNumOperands() && NumExplicitDefs; ++i) {
const MCOperand &Op = MCI.getOperand(i);
if (Op.isReg())
@@ -314,8 +315,8 @@ const InstrDesc &InstrBuilder::createIns
assert(STI.getSchedModel().hasInstrSchedModel() &&
"Itineraries are not yet supported!");
- unsigned short Opcode = MCI.getOpcode();
// Obtain the instruction descriptor from the opcode.
+ unsigned short Opcode = MCI.getOpcode();
const MCInstrDesc &MCDesc = MCII.get(Opcode);
const MCSchedModel &SM = STI.getSchedModel();
@@ -332,10 +333,23 @@ const InstrDesc &InstrBuilder::createIns
llvm::report_fatal_error("unable to resolve this variant class.");
}
+ // Check if this instruction is supported. Otherwise, report a fatal error.
+ const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
+ if (SCDesc.NumMicroOps == MCSchedClassDesc::InvalidNumMicroOps) {
+ std::string ToString;
+ llvm::raw_string_ostream OS(ToString);
+ WithColor::error() << "found an unsupported instruction in the input"
+ << " assembly sequence.\n";
+ MCIP.printInst(&MCI, OS, "", STI);
+ OS.flush();
+
+ WithColor::note() << "instruction: " << ToString << '\n';
+ llvm::report_fatal_error(
+ "Don't know how to analyze unsupported instructions.");
+ }
+
// Create a new empty descriptor.
std::unique_ptr<InstrDesc> ID = llvm::make_unique<InstrDesc>();
-
- const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
ID->NumMicroOps = SCDesc.NumMicroOps;
if (MCDesc.isCall()) {
@@ -357,8 +371,8 @@ const InstrDesc &InstrBuilder::createIns
initializeUsedResources(*ID, SCDesc, STI, ProcResourceMasks);
computeMaxLatency(*ID, MCDesc, SCDesc, STI);
- populateWrites(*ID, MCI, MCDesc, SCDesc, STI);
- populateReads(*ID, MCI, MCDesc, SCDesc, STI);
+ populateWrites(*ID, MCI, SchedClassID);
+ populateReads(*ID, MCI, SchedClassID);
LLVM_DEBUG(dbgs() << "\t\tMaxLatency=" << ID->MaxLatency << '\n');
LLVM_DEBUG(dbgs() << "\t\tNumMicroOps=" << ID->NumMicroOps << '\n');
@@ -428,8 +442,8 @@ InstrBuilder::createInstruction(const MC
// Initialize writes.
unsigned WriteIndex = 0;
for (const WriteDescriptor &WD : D.Writes) {
- unsigned RegID =
- WD.isImplicitWrite() ? WD.RegisterID : MCI.getOperand(WD.OpIndex).getReg();
+ unsigned RegID = WD.isImplicitWrite() ? WD.RegisterID
+ : MCI.getOperand(WD.OpIndex).getReg();
// Check if this is a optional definition that references NoReg.
if (WD.IsOptionalDef && !RegID) {
++WriteIndex;
Modified: llvm/trunk/tools/llvm-mca/InstrBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/InstrBuilder.h?rev=336543&r1=336542&r2=336543&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/InstrBuilder.h (original)
+++ llvm/trunk/tools/llvm-mca/InstrBuilder.h Mon Jul 9 05:30:55 2018
@@ -17,6 +17,7 @@
#include "Instruction.h"
#include "Support.h"
+#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
@@ -41,6 +42,7 @@ class InstrBuilder {
const llvm::MCInstrInfo &MCII;
const llvm::MCRegisterInfo &MRI;
const llvm::MCInstrAnalysis &MCIA;
+ llvm::MCInstPrinter &MCIP;
llvm::SmallVector<uint64_t, 8> ProcResourceMasks;
llvm::DenseMap<unsigned short, std::unique_ptr<const InstrDesc>> Descriptors;
@@ -51,11 +53,16 @@ class InstrBuilder {
InstrBuilder(const InstrBuilder &) = delete;
InstrBuilder &operator=(const InstrBuilder &) = delete;
+ void populateWrites(InstrDesc &ID, const llvm::MCInst &MCI,
+ unsigned SchedClassID);
+ void populateReads(InstrDesc &ID, const llvm::MCInst &MCI,
+ unsigned SchedClassID);
+
public:
InstrBuilder(const llvm::MCSubtargetInfo &sti, const llvm::MCInstrInfo &mcii,
const llvm::MCRegisterInfo &mri,
- const llvm::MCInstrAnalysis &mcia)
- : STI(sti), MCII(mcii), MRI(mri), MCIA(mcia),
+ const llvm::MCInstrAnalysis &mcia, llvm::MCInstPrinter &mcip)
+ : STI(sti), MCII(mcii), MRI(mri), MCIA(mcia), MCIP(mcip),
ProcResourceMasks(STI.getSchedModel().getNumProcResourceKinds()) {
computeProcResourceMasks(STI.getSchedModel(), ProcResourceMasks);
}
Modified: llvm/trunk/tools/llvm-mca/llvm-mca.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/llvm-mca.cpp?rev=336543&r1=336542&r2=336543&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/llvm-mca.cpp (original)
+++ llvm/trunk/tools/llvm-mca/llvm-mca.cpp Mon Jul 9 05:30:55 2018
@@ -460,7 +460,7 @@ int main(int argc, char **argv) {
Width = DispatchWidth;
// Create an instruction builder.
- mca::InstrBuilder IB(*STI, *MCII, *MRI, *MCIA);
+ mca::InstrBuilder IB(*STI, *MCII, *MRI, *MCIA, *IP);
// Create a context to control ownership of the pipeline hardware.
mca::Context MCA(*MRI, *STI);
More information about the llvm-commits
mailing list