[llvm] [IR] Add sparse instruction change printing (PR #221519)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 5 21:14:11 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-x86
Author: Yaxun (Sam) Liu (yxsamliu)
<details>
<summary>Changes</summary>
Full function dumps can hide small IR changes because inserting or
removing an unnamed value renumbers later values. They also produce a
large amount of output when most instructions do not change.
Add `-print-changed=inst` and `-print-changed=inst-quiet`. The new
diagnostic assigns process-local IDs to functions, instructions, basic
blocks, unnamed global and local values, and unnamed identified types.
It compares exact instruction text without hashes and reports
only added, removed, changed, or moved instructions and blocks.
Print call attributes inline so attribute-group renumbering does not
create false changes. Reuse adjacent snapshots when safe, and use the
buffered function instruction printer to avoid rebuilding printer state
for each instruction.
Follow the existing wildcard and module-scope function selection rules.
Use persistent function identity for comparisons so a rename does not
make unchanged instructions look moved.
These modes support new-pass-manager LLVM IR. Reject legacy and MIR
pipelines instead of silently falling back to full dumps, and own the
custom naming callbacks used by FunctionInstructionPrinter.
Add tests for sparse changes, moves, filters, stable identities, call
attributes, option interactions, and unsupported legacy and MIR use.
---
Patch is 55.18 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/221519.diff
15 Files Affected:
- (added) llvm/include/llvm/IR/FunctionInstructionPrinter.h (+61)
- (modified) llvm/include/llvm/IR/PrintPasses.h (+3-1)
- (modified) llvm/include/llvm/Passes/StandardInstrumentations.h (+17-3)
- (modified) llvm/lib/Analysis/CFGPrinter.cpp (+4-1)
- (modified) llvm/lib/IR/AsmWriter.cpp (+112-17)
- (modified) llvm/lib/IR/PrintPasses.cpp (+26-2)
- (modified) llvm/lib/Passes/CMakeLists.txt (+1)
- (added) llvm/lib/Passes/InstructionChangePrinter.cpp (+357)
- (added) llvm/lib/Passes/InstructionChangePrinter.h (+112)
- (modified) llvm/lib/Passes/StandardInstrumentations.cpp (+60-4)
- (added) llvm/test/CodeGen/X86/print-changed-instructions-unsupported.ll (+8)
- (added) llvm/test/Other/print-changed-instructions-function-name.ll (+8)
- (added) llvm/test/Other/print-changed-instructions-stable-names.ll (+62)
- (added) llvm/test/Other/print-changed-instructions.ll (+93)
- (modified) llvm/unittests/IR/AsmWriterTest.cpp (+103)
``````````diff
diff --git a/llvm/include/llvm/IR/FunctionInstructionPrinter.h b/llvm/include/llvm/IR/FunctionInstructionPrinter.h
new file mode 100644
index 0000000000000..b370771298fa0
--- /dev/null
+++ b/llvm/include/llvm/IR/FunctionInstructionPrinter.h
@@ -0,0 +1,61 @@
+//===- llvm/IR/FunctionInstructionPrinter.h ---------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_FUNCTIONINSTRUCTIONPRINTER_H
+#define LLVM_IR_FUNCTIONINSTRUCTIONPRINTER_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/Support/Compiler.h"
+#include <memory>
+
+namespace llvm {
+
+class Function;
+class Instruction;
+class ModuleSlotTracker;
+class Type;
+class Value;
+class raw_ostream;
+
+/// Print multiple instructions from one function without repeatedly creating
+/// the underlying assembly writer.
+///
+/// OS, MST, and F must remain valid for this object's lifetime. The function's
+/// IR must not be modified, and MST must not incorporate another function while
+/// the printer is in use. Each instruction is forwarded to OS before
+/// printInstruction returns, so callers can safely interleave other output.
+/// PrintValueName, when provided, is used for unnamed global and local values.
+/// PrintTypeName, when provided, is used for unnamed identified types. The
+/// callbacks are owned by this object. When PrintCallAttributesInline is true,
+/// function attributes on call-like instructions are printed inline instead
+/// of through module attribute-group slots.
+class LLVM_ABI FunctionInstructionPrinter {
+ struct Impl;
+ std::unique_ptr<Impl> P;
+
+public:
+ using ValueNameCallback = unique_function<void(raw_ostream &, const Value &)>;
+ using TypeNameCallback = unique_function<void(raw_ostream &, const Type &)>;
+
+ FunctionInstructionPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
+ const Function &F, bool IsForDebug = false,
+ ValueNameCallback PrintValueName = nullptr,
+ TypeNameCallback PrintTypeName = nullptr,
+ bool PrintCallAttributesInline = false);
+ ~FunctionInstructionPrinter();
+
+ FunctionInstructionPrinter(const FunctionInstructionPrinter &) = delete;
+ FunctionInstructionPrinter &
+ operator=(const FunctionInstructionPrinter &) = delete;
+
+ void printInstruction(const Instruction &I);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_IR_FUNCTIONINSTRUCTIONPRINTER_H
diff --git a/llvm/include/llvm/IR/PrintPasses.h b/llvm/include/llvm/IR/PrintPasses.h
index 170cb4ba38c97..5281befe40795 100644
--- a/llvm/include/llvm/IR/PrintPasses.h
+++ b/llvm/include/llvm/IR/PrintPasses.h
@@ -27,7 +27,9 @@ enum class ChangePrinter {
ColourDiffVerbose,
ColourDiffQuiet,
DotCfgVerbose,
- DotCfgQuiet
+ DotCfgQuiet,
+ InstructionVerbose,
+ InstructionQuiet
};
extern LLVM_ABI cl::opt<ChangePrinter> PrintChanged;
diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index beaad14201334..4dada362a5317 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -32,6 +32,8 @@
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Transforms/IPO/SampleProfileProbe.h"
+#include <memory>
+#include <optional>
#include <string>
#include <utility>
@@ -213,7 +215,8 @@ class PreservedCFGCheckerInstrumentation {
// 8. To compare two IR representations (of type \p T).
template <typename IRUnitT> class LLVM_ABI ChangeReporter {
protected:
- ChangeReporter(bool RunInVerboseMode) : VerboseMode(RunInVerboseMode) {}
+ ChangeReporter(bool RunInVerboseMode, bool ReuseAfterAsBefore = false)
+ : ReuseAfterAsBefore(ReuseAfterAsBefore), VerboseMode(RunInVerboseMode) {}
public:
virtual ~ChangeReporter();
@@ -255,6 +258,14 @@ template <typename IRUnitT> class LLVM_ABI ChangeReporter {
// Stack of IRs before passes and whether they matched the filters.
std::vector<BeforeIR> BeforeStack;
+ struct SnapshotCache {
+ IRUnitRef IR;
+ IRUnitT Representation;
+ };
+ std::optional<SnapshotCache> CachedSnapshot;
+ // Nested passes may mutate an outer IR unit between its callbacks.
+ unsigned ActivePasses = 0;
+ const bool ReuseAfterAsBefore;
// Is this the first IR seen?
bool InitialIR = true;
@@ -291,8 +302,7 @@ class LLVM_ABI TextChangeReporter : public ChangeReporter<IRUnitT> {
// included in this representation but it is massaged before reporting.
class LLVM_ABI IRChangedPrinter : public TextChangeReporter<std::string> {
public:
- IRChangedPrinter(bool VerboseMode)
- : TextChangeReporter<std::string>(VerboseMode) {}
+ IRChangedPrinter(bool VerboseMode);
~IRChangedPrinter() override;
void registerCallbacks(PassInstrumentationCallbacks &PIC);
@@ -304,6 +314,10 @@ class LLVM_ABI IRChangedPrinter : public TextChangeReporter<std::string> {
void handleAfter(StringRef PassID, std::string &Name,
const std::string &Before, const std::string &After,
IRUnitRef) override;
+
+private:
+ class InstructionChangeReporter;
+ std::unique_ptr<InstructionChangeReporter> InstructionChanges;
};
class LLVM_ABI IRChangedTester : public IRChangedPrinter {
diff --git a/llvm/lib/Analysis/CFGPrinter.cpp b/llvm/lib/Analysis/CFGPrinter.cpp
index 39108a906f081..f555b1470041d 100644
--- a/llvm/lib/Analysis/CFGPrinter.cpp
+++ b/llvm/lib/Analysis/CFGPrinter.cpp
@@ -19,6 +19,7 @@
#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/IR/FunctionInstructionPrinter.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
@@ -255,8 +256,10 @@ std::string DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel(
Node.printAsOperand(OS, false, *MST);
OS << ":\n";
+ FunctionInstructionPrinter InstructionPrinter(OS, *MST,
+ *Node.getParent());
for (const Instruction &Inst : Node) {
- Inst.print(OS, *MST, /* IsForDebug */ false);
+ InstructionPrinter.printInstruction(Inst);
OS << '\n';
}
}),
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 8e57bff1d36c9..500b58299ce19 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -44,6 +44,7 @@
#include "llvm/IR/DebugProgramInstruction.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/FunctionInstructionPrinter.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalObject.h"
@@ -548,8 +549,11 @@ namespace {
class TypePrinting {
public:
- TypePrinting(const Module *M = nullptr)
- : M(M), TypesIncorporated(M == nullptr) {}
+ TypePrinting(
+ const Module *M = nullptr,
+ FunctionInstructionPrinter::TypeNameCallback PrintTypeName = nullptr)
+ : M(M), TypesIncorporated(M == nullptr),
+ PrintTypeName(std::move(PrintTypeName)) {}
TypePrinting(const TypePrinting &) = delete;
TypePrinting &operator=(const TypePrinting &) = delete;
@@ -579,6 +583,7 @@ class TypePrinting {
DenseMap<StructType *, unsigned> Type2Number;
std::vector<StructType *> NumberedTypes;
+ FunctionInstructionPrinter::TypeNameCallback PrintTypeName;
};
} // end anonymous namespace
@@ -700,6 +705,9 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
if (!STy->getName().empty())
return printLLVMName(OS, STy->getName(), LocalPrefix);
+ if (PrintTypeName)
+ return PrintTypeName(OS, *STy);
+
incorporateTypes();
const auto I = Type2Number.find(STy);
if (I != Type2Number.end())
@@ -1526,10 +1534,14 @@ struct AsmWriterContext {
SlotTracker *Machine = nullptr;
const Module *Context = nullptr;
const ModuleSlotTracker *MST = nullptr;
+ FunctionInstructionPrinter::ValueNameCallback *PrintValueName = nullptr;
- AsmWriterContext(TypePrinting *TP, SlotTracker *ST, const Module *M = nullptr,
- const ModuleSlotTracker *MST = nullptr)
- : TypePrinter(TP), Machine(ST), Context(M), MST(MST) {}
+ AsmWriterContext(
+ TypePrinting *TP, SlotTracker *ST, const Module *M = nullptr,
+ const ModuleSlotTracker *MST = nullptr,
+ FunctionInstructionPrinter::ValueNameCallback *PrintValueName = nullptr)
+ : TypePrinter(TP), Machine(ST), Context(M), MST(MST),
+ PrintValueName(PrintValueName) {}
static AsmWriterContext &getEmpty() {
static AsmWriterContext EmptyCtx(nullptr, nullptr);
@@ -2853,6 +2865,12 @@ static void writeAsOperandInternal(raw_ostream &Out, const Value *V,
return;
}
+ if (WriterCtx.PrintValueName && (isa<GlobalValue>(V) || isa<Argument>(V) ||
+ isa<BasicBlock>(V) || isa<Instruction>(V))) {
+ (*WriterCtx.PrintValueName)(Out, *V);
+ return;
+ }
+
char Prefix = '%';
int Slot;
auto *Machine = WriterCtx.Machine;
@@ -2968,18 +2986,25 @@ class AssemblyWriter {
/// Synchronization scope names registered with LLVMContext.
SmallVector<StringRef, 8> SSNs;
DenseMap<const GlobalValueSummary *, GlobalValue::GUID> SummaryToGUIDMap;
+ FunctionInstructionPrinter::ValueNameCallback PrintValueName;
+ bool PrintCallAttributesInline = false;
public:
/// Construct an AssemblyWriter with an external SlotTracker
- AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M,
- AssemblyAnnotationWriter *AAW, bool IsForDebug,
- bool ShouldPreserveUseListOrder = false);
+ AssemblyWriter(
+ formatted_raw_ostream &o, SlotTracker &Mac, const Module *M,
+ AssemblyAnnotationWriter *AAW, bool IsForDebug,
+ bool ShouldPreserveUseListOrder = false,
+ FunctionInstructionPrinter::ValueNameCallback PrintValueName = nullptr,
+ FunctionInstructionPrinter::TypeNameCallback PrintTypeName = nullptr,
+ bool PrintCallAttributesInline = false);
AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
const ModuleSummaryIndex *Index, bool IsForDebug);
AsmWriterContext getContext() {
- return AsmWriterContext(&TypePrinter, &Machine, TheModule);
+ return AsmWriterContext(&TypePrinter, &Machine, TheModule, nullptr,
+ PrintValueName ? &PrintValueName : nullptr);
}
void printMDNodeBody(const MDNode *MD);
@@ -3004,6 +3029,7 @@ class AssemblyWriter {
void writeMDNode(unsigned Slot, const MDNode *Node);
void writeAttribute(const Attribute &Attr, bool InAttrGroup = false);
void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
+ void writeCallAttributes(const AttributeSet &AttrSet);
void writeAllAttributeGroups();
void printTypeIdentities();
@@ -3060,15 +3086,22 @@ class AssemblyWriter {
} // end anonymous namespace
-AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
- const Module *M, AssemblyAnnotationWriter *AAW,
- bool IsForDebug, bool ShouldPreserveUseListOrder)
- : Out(o), TheModule(M), Machine(Mac), TypePrinter(M), AnnotationWriter(AAW),
+AssemblyWriter::AssemblyWriter(
+ formatted_raw_ostream &o, SlotTracker &Mac, const Module *M,
+ AssemblyAnnotationWriter *AAW, bool IsForDebug,
+ bool ShouldPreserveUseListOrder,
+ FunctionInstructionPrinter::ValueNameCallback PrintValueName,
+ FunctionInstructionPrinter::TypeNameCallback PrintTypeName,
+ bool PrintCallAttributesInline)
+ : Out(o), TheModule(M), Machine(Mac),
+ TypePrinter(M, std::move(PrintTypeName)), AnnotationWriter(AAW),
IsForDebug(IsForDebug),
ShouldPreserveUseListOrder(
PreserveAssemblyUseListOrder.getNumOccurrences()
? PreserveAssemblyUseListOrder
- : ShouldPreserveUseListOrder) {
+ : ShouldPreserveUseListOrder),
+ PrintValueName(std::move(PrintValueName)),
+ PrintCallAttributesInline(PrintCallAttributesInline) {
if (!TheModule)
return;
for (const GlobalObject &GO : TheModule->global_objects())
@@ -4525,6 +4558,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
if (I.hasName()) {
printLLVMName(Out, &I);
Out << " = ";
+ } else if (!I.getType()->isVoidTy() && PrintValueName) {
+ PrintValueName(Out, I);
+ Out << " = ";
} else if (!I.getType()->isVoidTy()) {
// Print out the def slot taken.
int SlotNum = Machine.getLocalSlot(&I);
@@ -4772,7 +4808,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ')';
if (PAL.hasFnAttrs())
- Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttrs());
+ writeCallAttributes(PAL.getFnAttrs());
writeOperandBundles(CI);
} else if (const auto *II = dyn_cast<InvokeInst>(&I)) {
@@ -4810,7 +4846,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ')';
if (PAL.hasFnAttrs())
- Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttrs());
+ writeCallAttributes(PAL.getFnAttrs());
writeOperandBundles(II);
@@ -4850,7 +4886,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ')';
if (PAL.hasFnAttrs())
- Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttrs());
+ writeCallAttributes(PAL.getFnAttrs());
writeOperandBundles(CBI);
@@ -5140,6 +5176,14 @@ void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet,
}
}
+void AssemblyWriter::writeCallAttributes(const AttributeSet &AttrSet) {
+ Out << ' ';
+ if (PrintCallAttributesInline)
+ writeAttributeSet(AttrSet);
+ else
+ Out << '#' << Machine.getAttributeGroupSlot(AttrSet);
+}
+
void AssemblyWriter::writeAllAttributeGroups() {
std::vector<std::pair<AttributeSet, unsigned>> asVec;
asVec.resize(Machine.as_size());
@@ -5390,6 +5434,57 @@ void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST,
}
}
+struct FunctionInstructionPrinter::Impl {
+ const Function &F;
+ raw_ostream &Output;
+ // Collect the assembly writer's small writes before forwarding an
+ // instruction.
+ SmallString<1024> Buffer;
+ raw_svector_ostream BufferOS;
+ std::unique_ptr<SlotTracker> EmptySlotTable;
+ formatted_raw_ostream FormattedOS;
+ std::unique_ptr<AssemblyWriter> Writer;
+
+ Impl(raw_ostream &ROS, ModuleSlotTracker &MST, const Function &F,
+ bool IsForDebug,
+ FunctionInstructionPrinter::ValueNameCallback PrintValueName,
+ FunctionInstructionPrinter::TypeNameCallback PrintTypeName,
+ bool PrintCallAttributesInline)
+ : F(F), Output(ROS), BufferOS(Buffer), FormattedOS(BufferOS) {
+ FormattedOS.SetBufferSize(Buffer.capacity());
+ MST.incorporateFunction(F);
+ SlotTracker *SlotTable = MST.getMachine();
+ if (!SlotTable) {
+ EmptySlotTable =
+ std::make_unique<SlotTracker>(static_cast<const Module *>(nullptr));
+ SlotTable = EmptySlotTable.get();
+ }
+ Writer = std::make_unique<AssemblyWriter>(
+ FormattedOS, *SlotTable, F.getParent(), nullptr, IsForDebug,
+ /*ShouldPreserveUseListOrder=*/false, std::move(PrintValueName),
+ std::move(PrintTypeName), PrintCallAttributesInline);
+ }
+};
+
+FunctionInstructionPrinter::FunctionInstructionPrinter(
+ raw_ostream &OS, ModuleSlotTracker &MST, const Function &F, bool IsForDebug,
+ ValueNameCallback PrintValueName, TypeNameCallback PrintTypeName,
+ bool PrintCallAttributesInline)
+ : P(std::make_unique<Impl>(
+ OS, MST, F, IsForDebug, std::move(PrintValueName),
+ std::move(PrintTypeName), PrintCallAttributesInline)) {}
+
+FunctionInstructionPrinter::~FunctionInstructionPrinter() = default;
+
+void FunctionInstructionPrinter::printInstruction(const Instruction &I) {
+ assert(I.getFunction() == &P->F &&
+ "instruction must belong to the configured function");
+ P->Writer->printInstruction(I);
+ P->FormattedOS.flush();
+ P->Output.write(P->Buffer.data(), P->Buffer.size());
+ P->Buffer.clear();
+}
+
/// Print without a type, skipping the TypePrinting object.
///
/// \return \c true iff printing was successful.
diff --git a/llvm/lib/IR/PrintPasses.cpp b/llvm/lib/IR/PrintPasses.cpp
index b0a40dc317522..e7e947e3c8b9d 100644
--- a/llvm/lib/IR/PrintPasses.cpp
+++ b/llvm/lib/IR/PrintPasses.cpp
@@ -71,7 +71,18 @@ static cl::opt<bool> PrintAfterAll("print-after-all",
// -filter-print-source-locs and -filter-passes can be used to filter the
// output. This reporter relies on the linux diff utility to do comparisons and
// insert the prefixes. For systems that do not have the necessary facilities,
-// the error message will be shown in place of the expected output.
+// the error message will be shown in place of the expected output. The values
+// "inst" and "inst-quiet" produce a diagnostic stream of added, removed,
+// changed, or moved instructions and basic blocks. They compare exact
+// instruction text without hashing and give
+// unnamed values and identified types IDs that persist for this compiler
+// invocation. Call attributes are printed inline so module attribute-group
+// numbering does not affect comparisons. These modes are available only for
+// LLVM IR under the new pass manager. Changes outside instructions and basic
+// blocks, including debug records, are not reported. -print-before-changed has
+// no additional effect because removed and changed records already contain
+// their before text. A move is reported separately only when the instruction
+// text is unchanged; changed records include both the old and new locations.
cl::opt<ChangePrinter> llvm::PrintChanged(
"print-changed", cl::desc("Print changed IRs"), cl::Hidden,
cl::ValueOptional, cl::init(ChangePrinter::None),
@@ -89,6 +100,10 @@ cl::opt<ChangePrinter> llvm::PrintChanged(
"Create a website with graphical changes"),
clEnumValN(ChangePrinter::DotCfgQuiet, "dot-cfg-quiet",
"Create a website with graphical changes in quiet mode"),
+ clEnumValN(ChangePrinter::InstructionVerbose, "inst",
+ "Display instruction-level changes"),
+ clEnumValN(ChangePrinter::InstructionQuiet, "inst-quiet",
+ "Display instruction-level changes in quiet mode"),
// Sentinel value for unspecified option.
clEnumValN(ChangePrinter::Verbose, "", "")));
@@ -425,6 +440,11 @@ void llvm::reportChangedIR(StringRef Before, StringRef After,
StringRef PassName, StringRef PassID,
StringRef IRName, bool IsInteresting,
bool ShouldReport) {
+ if (PrintChanged == ChangePrinter::InstructionQuiet ||
+ PrintChanged == ChangePrinter::InstructionVerbose)
+ report_fatal_error("instruction-level change printing is only supported "
+ "for LLVM IR under the new pass manager");
+
if (!ShouldReport && IsInteresting)
return;
@@ -450,6 +470,9 @@ void llvm::reportChangedIR(StringRef Before, StringRef After,
case ChangePrinter::DotCfgVerbose: // unimplemented
errs() << After;
break;
+ case ChangePrinter::InstructionQuiet:
+ case ChangePrinter::InstructionVerbose:
+ llvm_unreachable("handled above");
case ChangePrinter::DiffQuiet:
case ChangePrinter::DiffVerbose:
case ChangePrinter::ColourDiffQuiet:
@@ -466,7 +489,8 @@ void llvm::reportChangedIR(StringRef Before, StringRef After,
}
} else if (llvm::is_contained({ChangePrinter::Verbose,
ChangePrinter::DiffVerbose,
- ChangePrinter::ColourDiffVerbose},
+ ChangePrinter::ColourDiffVerbose,
+ ChangePrinter::InstructionVerbose},
PrintChanged.getValue())) {
const char *Reason =
IsInteresting ? " omitted because no change" : " filtered out";
diff --git a/llvm/lib/Passes/CMakeLists.txt b/llvm/lib/Passes/CMa...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/221519
More information about the llvm-commits
mailing list