Skip to content

Commit e452750

Browse files
[llvm-mca] Add -skip-unsupported-instructions option
Prior to this patch, if llvm-mca encountered an instruction which parses but has no scheduler info, the instruction is always reported as unsupported, and llvm-mca halts with an error. However, it would still be useful to allow MCA to continue even in the case of instructions lacking scheduling information. Obviously if scheduling information is lacking, it's not possible to give an accurate analysis for those instructions, and therefore a warning is emitted. A user could previously have worked around such unsupported instructions manually by deleting such instructions from the input, but this provides them a way of doing this for bulk inputs where they may not have a list of such unsupported instructions to drop up front. Note that this behaviour of instructions with no scheduling information under -skip-unsupported-instructions is analagous to current instructions which fail to parse: those are currently dropped from the input with a message printed, after which the analysis continues.
1 parent f89f670 commit e452750

File tree

4 files changed

+69
-10
lines changed

4 files changed

+69
-10
lines changed

llvm/lib/MCA/InstrBuilder.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,8 +542,7 @@ InstrBuilder::createInstrDescImpl(const MCInst &MCI,
542542
const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
543543
if (SCDesc.NumMicroOps == MCSchedClassDesc::InvalidNumMicroOps) {
544544
return make_error<InstructionError<MCInst>>(
545-
"found an unsupported instruction in the input assembly sequence.",
546-
MCI);
545+
"found an unsupported instruction in the input assembly sequence", MCI);
547546
}
548547

549548
LLVM_DEBUG(dbgs() << "\n\t\tOpcode Name= " << MCII.getName(Opcode) << '\n');
Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
1-
# RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 %s 2>&1 | FileCheck %s
1+
# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -skip-unsupported-instructions %s |& FileCheck --check-prefix=CHECK-SKIP %s
2+
# RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 %s |& FileCheck --check-prefix=CHECK-ERROR %s
23

4+
# CHECK-SKIP: warning: found an unsupported instruction in the input assembly sequence, skipping with -skip-unsupported-instructions, note accuracy will be impacted:
5+
# CHECK-ERROR: error: found an unsupported instruction in the input assembly sequence, use -skip-unsupported-instructions to ignore.
6+
7+
# Currently lacks scheduling information and is therefore reported as unsupported by llvm-mca.
8+
# This may change some day in which case an alternative unsupported input would need to be found or the test removed.
39
bzhi %eax, %ebx, %ecx
410

5-
# CHECK: error: found an unsupported instruction in the input assembly sequence.
6-
# CHECK-NEXT: note: instruction: bzhil %eax, %ebx, %ecx
11+
# Supported instruction that may be analysed.
12+
add %eax, %eax
13+
14+
# CHECK-SKIP: Iterations: 100
15+
# CHECK-SKIP: Instructions: 100
16+
# CHECK-SKIP: Total Cycles: 103
17+
# CHECK-SKIP: Total uOps: 100
18+
19+
# CHECK-SKIP: Dispatch Width: 2
20+
# CHECK-SKIP: uOps Per Cycle: 0.97
21+
# CHECK-SKIP: IPC: 0.97
22+
# CHECK-SKIP: Block RThroughput: 0.5

llvm/tools/llvm-mca/CodeRegion.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#define LLVM_TOOLS_LLVM_MCA_CODEREGION_H
6060

6161
#include "llvm/ADT/ArrayRef.h"
62+
#include "llvm/ADT/SmallPtrSet.h"
6263
#include "llvm/ADT/SmallVector.h"
6364
#include "llvm/ADT/StringMap.h"
6465
#include "llvm/ADT/StringRef.h"
@@ -97,6 +98,20 @@ class CodeRegion {
9798
Instructions.emplace_back(Instruction);
9899
}
99100

101+
// Remove the given instructions from the set, for unsupported instructions
102+
// being skipped. Returns an ArrayRef for the updated vector of Instructions.
103+
[[nodiscard]] llvm::ArrayRef<llvm::MCInst>
104+
dropInstructions(const llvm::SmallPtrSetImpl<const llvm::MCInst *> &Insts) {
105+
if (Insts.empty())
106+
return Instructions;
107+
Instructions.erase(std::remove_if(Instructions.begin(), Instructions.end(),
108+
[&Insts](const llvm::MCInst &Inst) {
109+
return Insts.contains(&Inst);
110+
}),
111+
Instructions.end());
112+
return Instructions;
113+
}
114+
100115
llvm::SMLoc startLoc() const { return RangeStart; }
101116
llvm::SMLoc endLoc() const { return RangeEnd; }
102117

llvm/tools/llvm-mca/llvm-mca.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,11 @@ static cl::opt<bool> DisableInstrumentManager(
237237
"ignores instruments.)."),
238238
cl::cat(ViewOptions), cl::init(false));
239239

240+
static cl::opt<bool> SkipUnsupportedInstructions(
241+
"skip-unsupported-instructions",
242+
cl::desc("Make unsupported instruction errors into warnings."),
243+
cl::cat(ViewOptions), cl::init(false));
244+
240245
namespace {
241246

242247
const Target *getTarget(const char *ProgName) {
@@ -558,6 +563,7 @@ int main(int argc, char **argv) {
558563
assert(MAB && "Unable to create asm backend!");
559564

560565
json::Object JSONOutput;
566+
int NonEmptyRegions = 0;
561567
for (const std::unique_ptr<mca::AnalysisRegion> &Region : Regions) {
562568
// Skip empty code regions.
563569
if (Region->empty())
@@ -571,14 +577,13 @@ int main(int argc, char **argv) {
571577

572578
IPP->resetState();
573579

574-
DenseMap<const MCInst *, SmallVector<mca::Instrument *>>
575-
InstToInstruments;
580+
DenseMap<const MCInst *, SmallVector<mca::Instrument *>> InstToInstruments;
576581
SmallVector<std::unique_ptr<mca::Instruction>> LoweredSequence;
582+
SmallPtrSet<const MCInst *, 16> DroppedInsts;
577583
for (const MCInst &MCI : Insts) {
578584
SMLoc Loc = MCI.getLoc();
579585
const SmallVector<mca::Instrument *> Instruments =
580586
InstrumentRegions.getActiveInstruments(Loc);
581-
InstToInstruments.insert({&MCI, Instruments});
582587

583588
Expected<std::unique_ptr<mca::Instruction>> Inst =
584589
IB.createInstruction(MCI, Instruments);
@@ -588,7 +593,15 @@ int main(int argc, char **argv) {
588593
[&IP, &STI](const mca::InstructionError<MCInst> &IE) {
589594
std::string InstructionStr;
590595
raw_string_ostream SS(InstructionStr);
591-
WithColor::error() << IE.Message << '\n';
596+
if (SkipUnsupportedInstructions)
597+
WithColor::warning()
598+
<< IE.Message
599+
<< ", skipping with -skip-unsupported-instructions, "
600+
"note accuracy will be impacted:\n";
601+
else
602+
WithColor::error()
603+
<< IE.Message
604+
<< ", use -skip-unsupported-instructions to ignore.\n";
592605
IP->printInst(&IE.Inst, 0, "", *STI, SS);
593606
SS.flush();
594607
WithColor::note()
@@ -597,14 +610,25 @@ int main(int argc, char **argv) {
597610
// Default case.
598611
WithColor::error() << toString(std::move(NewE));
599612
}
613+
if (SkipUnsupportedInstructions) {
614+
DroppedInsts.insert(&MCI);
615+
continue;
616+
}
600617
return 1;
601618
}
602619

603620
IPP->postProcessInstruction(Inst.get(), MCI);
604-
621+
InstToInstruments.insert({&MCI, Instruments});
605622
LoweredSequence.emplace_back(std::move(Inst.get()));
606623
}
607624

625+
Insts = Region->dropInstructions(DroppedInsts);
626+
627+
// Skip empty regions.
628+
if (Insts.empty())
629+
continue;
630+
NonEmptyRegions++;
631+
608632
mca::CircularSourceMgr S(LoweredSequence,
609633
PrintInstructionTables ? 1 : Iterations);
610634

@@ -759,6 +783,11 @@ int main(int argc, char **argv) {
759783
++RegionIdx;
760784
}
761785

786+
if (NonEmptyRegions == 0) {
787+
WithColor::error() << "no assembly instructions found.\n";
788+
return 1;
789+
}
790+
762791
if (PrintJson)
763792
TOF->os() << formatv("{0:2}", json::Value(std::move(JSONOutput))) << "\n";
764793

0 commit comments

Comments
 (0)