[llvm] [MCA] Enable customization of individual instructions (PR #155420)
Roman Belenov via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 26 21:59:20 PDT 2025
https://github.com/r-belenov updated https://github.com/llvm/llvm-project/pull/155420
>From b1a67b7972a83cd1bc4a8bbede1e117d013c667b Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:00:10 +0300
Subject: [PATCH 01/14] Added interface to customize individual instructions
and possibility to change latency via special comments
* Added customizations to header
* Added customization to implementation
* Use default small vector size for custom instructions
* Typo fixed
* Use std::vector for custom descriptors
* Revert to SmallVector
* Erroneous dereference removed
* Introduced annotated instructions
* Updated getter method
* Updated getter usage
* Fixed type usage
* Revert to MCInst for regions
* Keep annotations in separate map
* Removed usage of annotated instruction
* Use std::optional
* Add setter/getter for explicit latency
* Set instruction latency according to annotation
* Simplify default return
* Revert to explicit default value
* Add missing brace
* Added missing field name
* Typo fixed
* Added missing namespace tags
* Whitespace removed
* Index annotations by smloc
* Search latency by SMLoc
* Use pointer as a map key
* Missing const added
* Added optional annotation to MCStreamerWrapper
* Added interface to annotate instructions
* Move annotations to CodeRegons
* Get explicit latency from Regions
* Erroneous dereference removed
* Add interface to pass latency to MCStreamerWrapper
* Fixed incorrect code placement
* Make Streamer available to CommentConsumer
* Move MCStreamerWrapper definition to make it visible in comment consumers
* Parse latency comment
* Fix drop_front usage
* Fix whitespace skipping on latency annotation
* Added test for latency annotation
* Additional test for latency annotations
* Use load in test instruction
* Use load in test instruction
* Added instruction builder customization
* Added customized instruction creation
* Pass builder to custom creation functor
* Added header with InstrBuilder declaration
* Typo fixed
* Added base for instruction customizations test
* Added missing result object
* Hardcode name for summary view
* Explicitly model single instruction
* Add actual custom latency test
* Typo fixed
* Pass latency to lambda body
* Adding missing const
* Specify lambda return type
* Erroneous argument removed
* Removed unnecessary lambda return type
* Code cleanup
* Code cleanup
---
llvm/include/llvm/MCA/InstrBuilder.h | 11 ++-
llvm/lib/MCA/InstrBuilder.cpp | 15 +++-
.../tools/llvm-mca/X86/llvm-mca-markers-13.s | 10 +++
.../tools/llvm-mca/X86/llvm-mca-markers-14.s | 10 +++
llvm/tools/llvm-mca/CodeRegion.h | 18 ++++
llvm/tools/llvm-mca/CodeRegionGenerator.cpp | 12 +++
llvm/tools/llvm-mca/CodeRegionGenerator.h | 85 +++++++++++--------
llvm/tools/llvm-mca/llvm-mca.cpp | 6 +-
llvm/unittests/tools/llvm-mca/MCATestBase.cpp | 5 +-
llvm/unittests/tools/llvm-mca/MCATestBase.h | 7 +-
.../tools/llvm-mca/X86/TestIncrementalMCA.cpp | 26 ++++++
11 files changed, 159 insertions(+), 46 deletions(-)
create mode 100644 llvm/test/tools/llvm-mca/X86/llvm-mca-markers-13.s
create mode 100644 llvm/test/tools/llvm-mca/X86/llvm-mca-markers-14.s
diff --git a/llvm/include/llvm/MCA/InstrBuilder.h b/llvm/include/llvm/MCA/InstrBuilder.h
index e0949d975fa99..9bb8c5b28fdad 100644
--- a/llvm/include/llvm/MCA/InstrBuilder.h
+++ b/llvm/include/llvm/MCA/InstrBuilder.h
@@ -25,6 +25,7 @@
#include "llvm/MCA/Support.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
+#include <functional>
namespace llvm {
namespace mca {
@@ -78,6 +79,10 @@ class InstrBuilder {
DenseMap<std::pair<hash_code, unsigned>, std::unique_ptr<const InstrDesc>>
VariantDescriptors;
+ // These descriptors are customized for particular instructions and cannot
+ // be reused
+ SmallVector<std::unique_ptr<const InstrDesc>> CustomDescriptors;
+
bool FirstCallInst;
bool FirstReturnInst;
unsigned CallLatency;
@@ -87,7 +92,8 @@ class InstrBuilder {
Expected<unsigned> getVariantSchedClassID(const MCInst &MCI, unsigned SchedClassID);
Expected<const InstrDesc &>
- createInstrDescImpl(const MCInst &MCI, const SmallVector<Instrument *> &IVec);
+ createInstrDescImpl(const MCInst &MCI, const SmallVector<Instrument *> &IVec,
+ std::function<void(InstrDesc&)> Customizer = {});
Expected<const InstrDesc &>
getOrCreateInstrDesc(const MCInst &MCI,
const SmallVector<Instrument *> &IVec);
@@ -116,7 +122,8 @@ class InstrBuilder {
void setInstRecycleCallback(InstRecycleCallback CB) { InstRecycleCB = CB; }
LLVM_ABI Expected<std::unique_ptr<Instruction>>
- createInstruction(const MCInst &MCI, const SmallVector<Instrument *> &IVec);
+ createInstruction(const MCInst &MCI, const SmallVector<Instrument *> &IVec,
+ std::function<void(InstrDesc&)> Customizer = {});
};
} // namespace mca
} // namespace llvm
diff --git a/llvm/lib/MCA/InstrBuilder.cpp b/llvm/lib/MCA/InstrBuilder.cpp
index cad25a6ddd3f5..4a0f09c4160d9 100644
--- a/llvm/lib/MCA/InstrBuilder.cpp
+++ b/llvm/lib/MCA/InstrBuilder.cpp
@@ -558,7 +558,8 @@ Expected<unsigned> InstrBuilder::getVariantSchedClassID(const MCInst &MCI,
Expected<const InstrDesc &>
InstrBuilder::createInstrDescImpl(const MCInst &MCI,
- const SmallVector<Instrument *> &IVec) {
+ const SmallVector<Instrument *> &IVec,
+ std::function<void(InstrDesc&)> Customizer) {
assert(STI.getSchedModel().hasInstrSchedModel() &&
"Itineraries are not yet supported!");
@@ -632,6 +633,12 @@ InstrBuilder::createInstrDescImpl(const MCInst &MCI,
return std::move(Err);
// Now add the new descriptor.
+
+ if (Customizer) {
+ Customizer(*ID);
+ return *CustomDescriptors.emplace_back(std::move(ID));
+ }
+
bool IsVariadic = MCDesc.isVariadic();
if ((ID->IsRecyclable = !IsVariadic && !IsVariant)) {
auto DKey = std::make_pair(MCI.getOpcode(), SchedClassID);
@@ -675,8 +682,10 @@ STATISTIC(NumVariantInst, "Number of MCInsts that doesn't have static Desc");
Expected<std::unique_ptr<Instruction>>
InstrBuilder::createInstruction(const MCInst &MCI,
- const SmallVector<Instrument *> &IVec) {
- Expected<const InstrDesc &> DescOrErr = getOrCreateInstrDesc(MCI, IVec);
+ const SmallVector<Instrument *> &IVec,
+ std::function<void(InstrDesc&)> Customizer) {
+ Expected<const InstrDesc &> DescOrErr = Customizer? createInstrDescImpl(MCI, IVec, Customizer) :
+ getOrCreateInstrDesc(MCI, IVec);
if (!DescOrErr)
return DescOrErr.takeError();
const InstrDesc &D = *DescOrErr;
diff --git a/llvm/test/tools/llvm-mca/X86/llvm-mca-markers-13.s b/llvm/test/tools/llvm-mca/X86/llvm-mca-markers-13.s
new file mode 100644
index 0000000000000..9115ffadbdaee
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/X86/llvm-mca-markers-13.s
@@ -0,0 +1,10 @@
+# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=10 %s 2>&1 | FileCheck %s
+
+add (%eax), %eax // LLVM-MCA-LATENCY : 100
+mov %eax, (%ebx)
+
+# CHECK: Iterations: 10
+# CHECK-NEXT: Instructions: 20
+# CHECK-NEXT: Total Cycles: 1004
+# CHECK-NEXT: Total uOps: 20
diff --git a/llvm/test/tools/llvm-mca/X86/llvm-mca-markers-14.s b/llvm/test/tools/llvm-mca/X86/llvm-mca-markers-14.s
new file mode 100644
index 0000000000000..41da9f4b4cef1
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/X86/llvm-mca-markers-14.s
@@ -0,0 +1,10 @@
+# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=10 %s 2>&1 | FileCheck %s
+
+add (%eax), %eax // LLVM-MCA-LATENCY : 100
+mov %eax, (%ebx) // LLVM-MCA-LATENCY : 100
+
+# CHECK: Iterations: 10
+# CHECK-NEXT: Instructions: 20
+# CHECK-NEXT: Total Cycles: 1103
+# CHECK-NEXT: Total uOps: 20
diff --git a/llvm/tools/llvm-mca/CodeRegion.h b/llvm/tools/llvm-mca/CodeRegion.h
index c04ea51169cfb..d16f976fe101e 100644
--- a/llvm/tools/llvm-mca/CodeRegion.h
+++ b/llvm/tools/llvm-mca/CodeRegion.h
@@ -69,10 +69,15 @@
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include <vector>
+#include <utility>
namespace llvm {
namespace mca {
+struct InstAnnotation {
+ std::optional<unsigned> Latency;
+};
+
/// A region of assembly code.
///
/// It identifies a sequence of machine instructions.
@@ -155,6 +160,9 @@ class CodeRegions {
llvm::StringMap<unsigned> ActiveRegions;
bool FoundErrors;
+ // Annotations specified in comments, indexed by SMLoc value
+ llvm::DenseMap<const char*, InstAnnotation> Annotations;
+
public:
CodeRegions(llvm::SourceMgr &S) : SM(S), FoundErrors(false) {}
virtual ~CodeRegions() = default;
@@ -170,6 +178,16 @@ class CodeRegions {
void addInstruction(const llvm::MCInst &Instruction);
llvm::SourceMgr &getSourceMgr() const { return SM; }
+ void Annotate(llvm::SMLoc Loc, const InstAnnotation& A) { Annotations[Loc.getPointer()] = A; }
+ std::optional<unsigned> getExplicitLatency(llvm::SMLoc Loc) const {
+ const auto It = Annotations.find(Loc.getPointer());
+ if (It != Annotations.end()) {
+ return It->second.Latency;
+ } else {
+ return {};
+ }
+ }
+
llvm::ArrayRef<llvm::MCInst> getInstructionSequence(unsigned Idx) const {
return Regions[Idx]->getInstructions();
}
diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
index f7f929e49ead9..767f92bf6f935 100644
--- a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
+++ b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
@@ -95,6 +95,18 @@ void AnalysisRegionCommentConsumer::HandleComment(SMLoc Loc,
return;
Comment = Comment.drop_front(Position);
+ if (Comment.starts_with("LLVM-MCA-LATENCY")) {
+ auto Parts = Comment.split(':');
+ Position = Parts.second.find_first_not_of(" \t");
+ if (Position >= Parts.second.size())
+ return;
+ auto LatStr = Parts.second.drop_front(Position);
+ unsigned Latency = 0;
+ if (!LatStr.getAsInteger(10, Latency))
+ Streamer.AddLatencyAnnotation(Latency);
+ return;
+ }
+
if (Comment.consume_front("LLVM-MCA-END")) {
// Skip spaces and tabs.
Position = Comment.find_first_not_of(" \t");
diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.h b/llvm/tools/llvm-mca/CodeRegionGenerator.h
index a48c67a22f27b..2c632be5e7f53 100644
--- a/llvm/tools/llvm-mca/CodeRegionGenerator.h
+++ b/llvm/tools/llvm-mca/CodeRegionGenerator.h
@@ -31,6 +31,50 @@
namespace llvm {
namespace mca {
+// This class provides the callbacks that occur when parsing input assembly.
+class MCStreamerWrapper : public MCStreamer {
+protected:
+ CodeRegions &Regions;
+ std::optional<InstAnnotation> CurrentAnnotation;
+
+public:
+ MCStreamerWrapper(MCContext &Context, mca::CodeRegions &R)
+ : MCStreamer(Context), Regions(R) {}
+
+ // We only want to intercept the emission of new instructions.
+ void emitInstruction(const MCInst &Inst,
+ const MCSubtargetInfo & /* unused */) override {
+ Regions.addInstruction(Inst);
+ if (CurrentAnnotation) {
+ Regions.Annotate(Inst.getLoc(), *CurrentAnnotation);
+ CurrentAnnotation = {};
+ }
+ }
+
+ void AddLatencyAnnotation(unsigned Lat) {
+ if (!CurrentAnnotation) CurrentAnnotation = InstAnnotation();
+ CurrentAnnotation->Latency = Lat;
+ }
+
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
+ return true;
+ }
+
+ void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ Align ByteAlignment) override {}
+ void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, Align ByteAlignment = Align(1),
+ SMLoc Loc = SMLoc()) override {}
+ void beginCOFFSymbolDef(const MCSymbol *Symbol) override {}
+ void emitCOFFSymbolStorageClass(int StorageClass) override {}
+ void emitCOFFSymbolType(int Type) override {}
+ void endCOFFSymbolDef() override {}
+
+ ArrayRef<MCInst> GetInstructionSequence(unsigned Index) const {
+ return Regions.getInstructionSequence(Index);
+ }
+};
+
class MCACommentConsumer : public AsmCommentConsumer {
protected:
bool FoundError = false;
@@ -44,9 +88,10 @@ class MCACommentConsumer : public AsmCommentConsumer {
/// A comment consumer that parses strings. The only valid tokens are strings.
class AnalysisRegionCommentConsumer : public MCACommentConsumer {
AnalysisRegions &Regions;
+ MCStreamerWrapper &Streamer;
public:
- AnalysisRegionCommentConsumer(AnalysisRegions &R) : Regions(R) {}
+ AnalysisRegionCommentConsumer(AnalysisRegions &R, MCStreamerWrapper &S) : Regions(R), Streamer(S) {}
/// Parses a comment. It begins a new region if it is of the form
/// LLVM-MCA-BEGIN. It ends a region if it is of the form LLVM-MCA-END.
@@ -82,40 +127,6 @@ class InstrumentRegionCommentConsumer : public MCACommentConsumer {
InstrumentManager &getInstrumentManager() { return IM; }
};
-// This class provides the callbacks that occur when parsing input assembly.
-class MCStreamerWrapper : public MCStreamer {
-protected:
- CodeRegions &Regions;
-
-public:
- MCStreamerWrapper(MCContext &Context, mca::CodeRegions &R)
- : MCStreamer(Context), Regions(R) {}
-
- // We only want to intercept the emission of new instructions.
- void emitInstruction(const MCInst &Inst,
- const MCSubtargetInfo & /* unused */) override {
- Regions.addInstruction(Inst);
- }
-
- bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
- return true;
- }
-
- void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- Align ByteAlignment) override {}
- void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
- uint64_t Size = 0, Align ByteAlignment = Align(1),
- SMLoc Loc = SMLoc()) override {}
- void beginCOFFSymbolDef(const MCSymbol *Symbol) override {}
- void emitCOFFSymbolStorageClass(int StorageClass) override {}
- void emitCOFFSymbolType(int Type) override {}
- void endCOFFSymbolDef() override {}
-
- ArrayRef<MCInst> GetInstructionSequence(unsigned Index) const {
- return Regions.getInstructionSequence(Index);
- }
-};
-
class InstrumentMCStreamer : public MCStreamerWrapper {
InstrumentManager &IM;
@@ -210,15 +221,15 @@ class AsmCodeRegionGenerator : public virtual CodeRegionGenerator {
class AsmAnalysisRegionGenerator final : public AnalysisRegionGenerator,
public AsmCodeRegionGenerator {
- AnalysisRegionCommentConsumer CC;
MCStreamerWrapper Streamer;
+ AnalysisRegionCommentConsumer CC;
public:
AsmAnalysisRegionGenerator(const Target &T, llvm::SourceMgr &SM, MCContext &C,
const MCAsmInfo &A, const MCSubtargetInfo &S,
const MCInstrInfo &I)
: AnalysisRegionGenerator(SM), AsmCodeRegionGenerator(T, C, A, S, I),
- CC(Regions), Streamer(Ctx, Regions) {}
+ Streamer(Ctx, Regions), CC(Regions, Streamer) {}
MCACommentConsumer *getCommentConsumer() override { return &CC; };
CodeRegions &getRegions() override { return Regions; };
diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp
index 4b0611186d21f..5f653ffcd83ed 100644
--- a/llvm/tools/llvm-mca/llvm-mca.cpp
+++ b/llvm/tools/llvm-mca/llvm-mca.cpp
@@ -633,7 +633,11 @@ int main(int argc, char **argv) {
const SmallVector<mca::Instrument *> Instruments =
InstrumentRegions.getActiveInstruments(Loc);
- Expected<std::unique_ptr<mca::Instruction>> Inst =
+ auto Latency = Regions.getExplicitLatency(Loc);
+ Expected<std::unique_ptr<mca::Instruction>> Inst = Latency ?
+ IB.createInstruction(MCI, Instruments, [=](llvm::mca::InstrDesc& ID) {
+ for (auto& W : ID.Writes) W.Latency = *Latency;
+ ID.MaxLatency = *Latency; }) :
IB.createInstruction(MCI, Instruments);
if (!Inst) {
if (auto NewE = handleErrors(
diff --git a/llvm/unittests/tools/llvm-mca/MCATestBase.cpp b/llvm/unittests/tools/llvm-mca/MCATestBase.cpp
index cd3258ef96d64..96413168b8f5e 100644
--- a/llvm/unittests/tools/llvm-mca/MCATestBase.cpp
+++ b/llvm/unittests/tools/llvm-mca/MCATestBase.cpp
@@ -61,7 +61,8 @@ void MCATestBase::SetUp() {
Error MCATestBase::runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts,
ArrayRef<mca::View *> Views,
- const mca::PipelineOptions *PO) {
+ const mca::PipelineOptions *PO,
+ Builder B) {
mca::Context MCA(*MRI, *STI);
// Default InstrumentManager
@@ -72,7 +73,7 @@ Error MCATestBase::runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts,
SmallVector<std::unique_ptr<mca::Instruction>> LoweredInsts;
for (const auto &MCI : Insts) {
Expected<std::unique_ptr<mca::Instruction>> Inst =
- IB.createInstruction(MCI, Instruments);
+ B ? B(IB, MCI, Instruments) : IB.createInstruction(MCI, Instruments);
if (!Inst) {
if (auto NewE =
handleErrors(Inst.takeError(),
diff --git a/llvm/unittests/tools/llvm-mca/MCATestBase.h b/llvm/unittests/tools/llvm-mca/MCATestBase.h
index 66e20a45c96ce..399a8e892bc28 100644
--- a/llvm/unittests/tools/llvm-mca/MCATestBase.h
+++ b/llvm/unittests/tools/llvm-mca/MCATestBase.h
@@ -24,6 +24,7 @@
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/MCA/Context.h"
+#include "llvm/MCA/InstrBuilder.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/TargetParser/Triple.h"
@@ -70,12 +71,16 @@ class MCATestBase : public ::testing::Test {
void SetUp() override;
+ using Builder = std::function<Expected<std::unique_ptr<mca::Instruction>>
+ (mca::InstrBuilder&, const MCInst&, const SmallVector<mca::Instrument *>&)>;
+
/// Utility function to run MCA with (nearly) the same configuration as the
/// `llvm-mca` tool to verify result correctness.
/// This function only displays on SummaryView by default.
virtual Error runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts,
ArrayRef<mca::View *> Views = {},
- const mca::PipelineOptions *PO = nullptr);
+ const mca::PipelineOptions *PO = nullptr,
+ Builder B = {});
};
} // end namespace mca
diff --git a/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp b/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp
index 1a14c687295ca..cf66460b11fc8 100644
--- a/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp
+++ b/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp
@@ -234,3 +234,29 @@ TEST_F(X86TestBase, TestVariantInstructionsSameAddress) {
Expected<unsigned> Cycles = P->run();
ASSERT_TRUE(static_cast<bool>(Cycles));
}
+
+TEST_F(X86TestBase, TestInstructionCustomization) {
+ const unsigned ExplicitLatency = 100;
+ SmallVector<MCInst> MCIs;
+ MCInst InstructionToAdd = MCInstBuilder(X86::XOR64rr)
+ .addReg(X86::RAX)
+ .addReg(X86::RAX)
+ .addReg(X86::RAX);
+ MCIs.push_back(InstructionToAdd);
+
+ // Run the baseline.
+ json::Object BaselineResult;
+ auto E = runBaselineMCA(BaselineResult, MCIs, {}, nullptr,
+ [=](InstrBuilder& IB, const MCInst& MCI, const SmallVector<Instrument*>& Instruments) {
+ return IB.createInstruction(MCI, Instruments,
+ [=](InstrDesc& ID) {
+ for (auto& W : ID.Writes) W.Latency = ExplicitLatency;
+ ID.MaxLatency = ExplicitLatency;
+ });
+ });
+ auto *BaselineObj = BaselineResult.getObject("SummaryView");
+ auto V = BaselineObj->getInteger("TotalCycles");
+ ASSERT_TRUE(V);
+ // Additional 3 cycles for Dispatch, Executed and Retired states
+ ASSERT_EQ(unsigned(*V), ExplicitLatency + 3) << "Total cycles do not match";
+}
>From 4abee0f229ed6859ed9f0f86662a75f34d788664 Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:28:21 +0300
Subject: [PATCH 02/14] Fix formatting
---
llvm/include/llvm/MCA/InstrBuilder.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/MCA/InstrBuilder.h b/llvm/include/llvm/MCA/InstrBuilder.h
index 9bb8c5b28fdad..7b2fbde2c4a0e 100644
--- a/llvm/include/llvm/MCA/InstrBuilder.h
+++ b/llvm/include/llvm/MCA/InstrBuilder.h
@@ -93,7 +93,7 @@ class InstrBuilder {
Expected<unsigned> getVariantSchedClassID(const MCInst &MCI, unsigned SchedClassID);
Expected<const InstrDesc &>
createInstrDescImpl(const MCInst &MCI, const SmallVector<Instrument *> &IVec,
- std::function<void(InstrDesc&)> Customizer = {});
+ std::function<void(InstrDesc &)> Customizer = {});
Expected<const InstrDesc &>
getOrCreateInstrDesc(const MCInst &MCI,
const SmallVector<Instrument *> &IVec);
@@ -123,7 +123,7 @@ class InstrBuilder {
LLVM_ABI Expected<std::unique_ptr<Instruction>>
createInstruction(const MCInst &MCI, const SmallVector<Instrument *> &IVec,
- std::function<void(InstrDesc&)> Customizer = {});
+ std::function<void(InstrDesc &)> Customizer = {});
};
} // namespace mca
} // namespace llvm
>From 1298dd3391061b66c57bd69b58a44894f001f4fe Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:31:59 +0300
Subject: [PATCH 03/14] Fix formatting
---
llvm/lib/MCA/InstrBuilder.cpp | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/MCA/InstrBuilder.cpp b/llvm/lib/MCA/InstrBuilder.cpp
index 4a0f09c4160d9..8b3e52a871f71 100644
--- a/llvm/lib/MCA/InstrBuilder.cpp
+++ b/llvm/lib/MCA/InstrBuilder.cpp
@@ -559,7 +559,7 @@ Expected<unsigned> InstrBuilder::getVariantSchedClassID(const MCInst &MCI,
Expected<const InstrDesc &>
InstrBuilder::createInstrDescImpl(const MCInst &MCI,
const SmallVector<Instrument *> &IVec,
- std::function<void(InstrDesc&)> Customizer) {
+ std::function<void(InstrDesc &)> Customizer) {
assert(STI.getSchedModel().hasInstrSchedModel() &&
"Itineraries are not yet supported!");
@@ -638,7 +638,7 @@ InstrBuilder::createInstrDescImpl(const MCInst &MCI,
Customizer(*ID);
return *CustomDescriptors.emplace_back(std::move(ID));
}
-
+
bool IsVariadic = MCDesc.isVariadic();
if ((ID->IsRecyclable = !IsVariadic && !IsVariant)) {
auto DKey = std::make_pair(MCI.getOpcode(), SchedClassID);
@@ -683,9 +683,10 @@ STATISTIC(NumVariantInst, "Number of MCInsts that doesn't have static Desc");
Expected<std::unique_ptr<Instruction>>
InstrBuilder::createInstruction(const MCInst &MCI,
const SmallVector<Instrument *> &IVec,
- std::function<void(InstrDesc&)> Customizer) {
- Expected<const InstrDesc &> DescOrErr = Customizer? createInstrDescImpl(MCI, IVec, Customizer) :
- getOrCreateInstrDesc(MCI, IVec);
+ std::function<void(InstrDesc &)> Customizer) {
+ Expected<const InstrDesc &> DescOrErr =
+ Customizer ? createInstrDescImpl(MCI, IVec, Customizer)
+ : getOrCreateInstrDesc(MCI, IVec);
if (!DescOrErr)
return DescOrErr.takeError();
const InstrDesc &D = *DescOrErr;
>From b5c3b952f9295d3ed4e493d2d3d2dd6c88a5adf2 Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:35:46 +0300
Subject: [PATCH 04/14] Fix formatting
---
llvm/tools/llvm-mca/CodeRegion.h | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/tools/llvm-mca/CodeRegion.h b/llvm/tools/llvm-mca/CodeRegion.h
index d16f976fe101e..0b5385a6d7ad1 100644
--- a/llvm/tools/llvm-mca/CodeRegion.h
+++ b/llvm/tools/llvm-mca/CodeRegion.h
@@ -68,8 +68,8 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
-#include <vector>
#include <utility>
+#include <vector>
namespace llvm {
namespace mca {
@@ -161,7 +161,7 @@ class CodeRegions {
bool FoundErrors;
// Annotations specified in comments, indexed by SMLoc value
- llvm::DenseMap<const char*, InstAnnotation> Annotations;
+ llvm::DenseMap<const char *, InstAnnotation> Annotations;
public:
CodeRegions(llvm::SourceMgr &S) : SM(S), FoundErrors(false) {}
@@ -178,7 +178,9 @@ class CodeRegions {
void addInstruction(const llvm::MCInst &Instruction);
llvm::SourceMgr &getSourceMgr() const { return SM; }
- void Annotate(llvm::SMLoc Loc, const InstAnnotation& A) { Annotations[Loc.getPointer()] = A; }
+ void Annotate(llvm::SMLoc Loc, const InstAnnotation& A) {
+ Annotations[Loc.getPointer()] = A;
+ }
std::optional<unsigned> getExplicitLatency(llvm::SMLoc Loc) const {
const auto It = Annotations.find(Loc.getPointer());
if (It != Annotations.end()) {
>From 302b994407840ae4a4039ce5cbb25de7edf7d2f5 Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:37:17 +0300
Subject: [PATCH 05/14] Fix formatting
---
llvm/tools/llvm-mca/CodeRegionGenerator.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
index 767f92bf6f935..0d400760f17e1 100644
--- a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
+++ b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp
@@ -96,15 +96,15 @@ void AnalysisRegionCommentConsumer::HandleComment(SMLoc Loc,
Comment = Comment.drop_front(Position);
if (Comment.starts_with("LLVM-MCA-LATENCY")) {
- auto Parts = Comment.split(':');
- Position = Parts.second.find_first_not_of(" \t");
- if (Position >= Parts.second.size())
- return;
- auto LatStr = Parts.second.drop_front(Position);
- unsigned Latency = 0;
- if (!LatStr.getAsInteger(10, Latency))
- Streamer.AddLatencyAnnotation(Latency);
+ auto Parts = Comment.split(':');
+ Position = Parts.second.find_first_not_of(" \t");
+ if (Position >= Parts.second.size())
return;
+ auto LatStr = Parts.second.drop_front(Position);
+ unsigned Latency = 0;
+ if (!LatStr.getAsInteger(10, Latency))
+ Streamer.AddLatencyAnnotation(Latency);
+ return;
}
if (Comment.consume_front("LLVM-MCA-END")) {
>From 23389785357f8cf7a11ce7050cf8904eb4915db2 Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:39:13 +0300
Subject: [PATCH 06/14] Fix formatting
---
llvm/tools/llvm-mca/CodeRegionGenerator.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.h b/llvm/tools/llvm-mca/CodeRegionGenerator.h
index 2c632be5e7f53..1f43a8b26c471 100644
--- a/llvm/tools/llvm-mca/CodeRegionGenerator.h
+++ b/llvm/tools/llvm-mca/CodeRegionGenerator.h
@@ -52,7 +52,8 @@ class MCStreamerWrapper : public MCStreamer {
}
void AddLatencyAnnotation(unsigned Lat) {
- if (!CurrentAnnotation) CurrentAnnotation = InstAnnotation();
+ if (!CurrentAnnotation)
+ CurrentAnnotation = InstAnnotation();
CurrentAnnotation->Latency = Lat;
}
@@ -91,7 +92,8 @@ class AnalysisRegionCommentConsumer : public MCACommentConsumer {
MCStreamerWrapper &Streamer;
public:
- AnalysisRegionCommentConsumer(AnalysisRegions &R, MCStreamerWrapper &S) : Regions(R), Streamer(S) {}
+ AnalysisRegionCommentConsumer(AnalysisRegions &R, MCStreamerWrapper &S)
+ : Regions(R), Streamer(S) {}
/// Parses a comment. It begins a new region if it is of the form
/// LLVM-MCA-BEGIN. It ends a region if it is of the form LLVM-MCA-END.
>From 0be9fbf1719caf78d8db77d3c26249ee30dc2e3a Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:41:47 +0300
Subject: [PATCH 07/14] Fix formatting
---
llvm/tools/llvm-mca/llvm-mca.cpp | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp
index 5f653ffcd83ed..902a603a8e7dc 100644
--- a/llvm/tools/llvm-mca/llvm-mca.cpp
+++ b/llvm/tools/llvm-mca/llvm-mca.cpp
@@ -634,11 +634,14 @@ int main(int argc, char **argv) {
InstrumentRegions.getActiveInstruments(Loc);
auto Latency = Regions.getExplicitLatency(Loc);
- Expected<std::unique_ptr<mca::Instruction>> Inst = Latency ?
- IB.createInstruction(MCI, Instruments, [=](llvm::mca::InstrDesc& ID) {
- for (auto& W : ID.Writes) W.Latency = *Latency;
- ID.MaxLatency = *Latency; }) :
- IB.createInstruction(MCI, Instruments);
+ Expected<std::unique_ptr<mca::Instruction>> Inst =
+ Latency ? IB.createInstruction(MCI, Instruments,
+ [=](llvm::mca::InstrDesc& ID) {
+ for (auto& W : ID.Writes)
+ W.Latency = *Latency;
+ ID.MaxLatency = *Latency;
+ })
+ : IB.createInstruction(MCI, Instruments);
if (!Inst) {
if (auto NewE = handleErrors(
Inst.takeError(),
>From f1ad060d678b53d1bdd4a6c0659bbfb0764d9cfb Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:43:15 +0300
Subject: [PATCH 08/14] Fix formatting
---
llvm/unittests/tools/llvm-mca/MCATestBase.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/unittests/tools/llvm-mca/MCATestBase.cpp b/llvm/unittests/tools/llvm-mca/MCATestBase.cpp
index 96413168b8f5e..e2ff1dbe73a49 100644
--- a/llvm/unittests/tools/llvm-mca/MCATestBase.cpp
+++ b/llvm/unittests/tools/llvm-mca/MCATestBase.cpp
@@ -61,8 +61,7 @@ void MCATestBase::SetUp() {
Error MCATestBase::runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts,
ArrayRef<mca::View *> Views,
- const mca::PipelineOptions *PO,
- Builder B) {
+ const mca::PipelineOptions *PO, Builder B) {
mca::Context MCA(*MRI, *STI);
// Default InstrumentManager
>From 757fec3e279200fe3d7a9abdded8b412fbec9ac5 Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:44:43 +0300
Subject: [PATCH 09/14] Fix formatting
---
llvm/unittests/tools/llvm-mca/MCATestBase.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/unittests/tools/llvm-mca/MCATestBase.h b/llvm/unittests/tools/llvm-mca/MCATestBase.h
index 399a8e892bc28..557da7b3d0d05 100644
--- a/llvm/unittests/tools/llvm-mca/MCATestBase.h
+++ b/llvm/unittests/tools/llvm-mca/MCATestBase.h
@@ -71,8 +71,9 @@ class MCATestBase : public ::testing::Test {
void SetUp() override;
- using Builder = std::function<Expected<std::unique_ptr<mca::Instruction>>
- (mca::InstrBuilder&, const MCInst&, const SmallVector<mca::Instrument *>&)>;
+ using Builder = std::function<Expected<std::unique_ptr<mca::Instruction>>(
+ mca::InstrBuilder&, const MCInst&,
+ const SmallVector<mca::Instrument *> &)>;
/// Utility function to run MCA with (nearly) the same configuration as the
/// `llvm-mca` tool to verify result correctness.
>From 452bb402949d7c427417d88d96c5ed220237a300 Mon Sep 17 00:00:00 2001
From: Roman Belenov <103195329+r-belenov at users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:47:02 +0300
Subject: [PATCH 10/14] Fix formatting
---
.../tools/llvm-mca/X86/TestIncrementalMCA.cpp | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp b/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp
index cf66460b11fc8..8aa879b3e053d 100644
--- a/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp
+++ b/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp
@@ -236,7 +236,7 @@ TEST_F(X86TestBase, TestVariantInstructionsSameAddress) {
}
TEST_F(X86TestBase, TestInstructionCustomization) {
- const unsigned ExplicitLatency = 100;
+ const unsigned ExplicitLatency = 100;
SmallVector<MCInst> MCIs;
MCInst InstructionToAdd = MCInstBuilder(X86::XOR64rr)
.addReg(X86::RAX)
@@ -247,13 +247,15 @@ TEST_F(X86TestBase, TestInstructionCustomization) {
// Run the baseline.
json::Object BaselineResult;
auto E = runBaselineMCA(BaselineResult, MCIs, {}, nullptr,
- [=](InstrBuilder& IB, const MCInst& MCI, const SmallVector<Instrument*>& Instruments) {
- return IB.createInstruction(MCI, Instruments,
- [=](InstrDesc& ID) {
- for (auto& W : ID.Writes) W.Latency = ExplicitLatency;
- ID.MaxLatency = ExplicitLatency;
- });
- });
+ [=](InstrBuilder &IB, const MCInst &MCI,
+ const SmallVector<Instrument *> &Instruments) {
+ return IB.createInstruction(
+ MCI, Instruments, [=](InstrDesc &ID) {
+ for (auto &W : ID.Writes)
+ W.Latency = ExplicitLatency;
+ ID.MaxLatency = ExplicitLatency;
+ });
+ });
auto *BaselineObj = BaselineResult.getObject("SummaryView");
auto V = BaselineObj->getInteger("TotalCycles");
ASSERT_TRUE(V);
>From 4d655f875362cbae9fc17febfa78fc874a168c86 Mon Sep 17 00:00:00 2001
From: Roman Belenov <rbelenov at gmail.com>
Date: Tue, 26 Aug 2025 17:51:49 +0300
Subject: [PATCH 11/14] Fix formatting
---
llvm/tools/llvm-mca/CodeRegion.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/tools/llvm-mca/CodeRegion.h b/llvm/tools/llvm-mca/CodeRegion.h
index 0b5385a6d7ad1..52c0854779be6 100644
--- a/llvm/tools/llvm-mca/CodeRegion.h
+++ b/llvm/tools/llvm-mca/CodeRegion.h
@@ -178,7 +178,7 @@ class CodeRegions {
void addInstruction(const llvm::MCInst &Instruction);
llvm::SourceMgr &getSourceMgr() const { return SM; }
- void Annotate(llvm::SMLoc Loc, const InstAnnotation& A) {
+ void Annotate(llvm::SMLoc Loc, const InstAnnotation &A) {
Annotations[Loc.getPointer()] = A;
}
std::optional<unsigned> getExplicitLatency(llvm::SMLoc Loc) const {
>From ef2a0f0106358ee44d1a036e8b6cf2ab6fc50179 Mon Sep 17 00:00:00 2001
From: Roman Belenov <rbelenov at gmail.com>
Date: Tue, 26 Aug 2025 17:52:56 +0300
Subject: [PATCH 12/14] Fix formatting
---
llvm/tools/llvm-mca/llvm-mca.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp
index 902a603a8e7dc..73ac11794154f 100644
--- a/llvm/tools/llvm-mca/llvm-mca.cpp
+++ b/llvm/tools/llvm-mca/llvm-mca.cpp
@@ -636,8 +636,8 @@ int main(int argc, char **argv) {
auto Latency = Regions.getExplicitLatency(Loc);
Expected<std::unique_ptr<mca::Instruction>> Inst =
Latency ? IB.createInstruction(MCI, Instruments,
- [=](llvm::mca::InstrDesc& ID) {
- for (auto& W : ID.Writes)
+ [=](llvm::mca::InstrDesc &ID) {
+ for (auto &W : ID.Writes)
W.Latency = *Latency;
ID.MaxLatency = *Latency;
})
>From 77eefdbeefd5f004d9b7c304e963fe44d65549b4 Mon Sep 17 00:00:00 2001
From: Roman Belenov <rbelenov at gmail.com>
Date: Tue, 26 Aug 2025 17:54:25 +0300
Subject: [PATCH 13/14] Fix formatting
---
llvm/unittests/tools/llvm-mca/MCATestBase.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/unittests/tools/llvm-mca/MCATestBase.h b/llvm/unittests/tools/llvm-mca/MCATestBase.h
index 557da7b3d0d05..e991252cd3efd 100644
--- a/llvm/unittests/tools/llvm-mca/MCATestBase.h
+++ b/llvm/unittests/tools/llvm-mca/MCATestBase.h
@@ -72,7 +72,7 @@ class MCATestBase : public ::testing::Test {
void SetUp() override;
using Builder = std::function<Expected<std::unique_ptr<mca::Instruction>>(
- mca::InstrBuilder&, const MCInst&,
+ mca::InstrBuilder &, const MCInst &,
const SmallVector<mca::Instrument *> &)>;
/// Utility function to run MCA with (nearly) the same configuration as the
>From 6e0d12b6aa58c9608b677da571781157e07bb4af Mon Sep 17 00:00:00 2001
From: Roman Belenov <rbelenov at gmail.com>
Date: Wed, 27 Aug 2025 07:59:05 +0300
Subject: [PATCH 14/14] Using function_ref to pass function arguments
* Switch to function_ref
* Switch to function_ref
* Check pipeline execution status
* Switch to function_ref
---
llvm/include/llvm/MCA/InstrBuilder.h | 4 ++--
llvm/lib/MCA/InstrBuilder.cpp | 4 ++--
llvm/unittests/tools/llvm-mca/MCATestBase.h | 2 +-
llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp | 1 +
4 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/MCA/InstrBuilder.h b/llvm/include/llvm/MCA/InstrBuilder.h
index 7b2fbde2c4a0e..6779d27dcca3a 100644
--- a/llvm/include/llvm/MCA/InstrBuilder.h
+++ b/llvm/include/llvm/MCA/InstrBuilder.h
@@ -93,7 +93,7 @@ class InstrBuilder {
Expected<unsigned> getVariantSchedClassID(const MCInst &MCI, unsigned SchedClassID);
Expected<const InstrDesc &>
createInstrDescImpl(const MCInst &MCI, const SmallVector<Instrument *> &IVec,
- std::function<void(InstrDesc &)> Customizer = {});
+ function_ref<void(InstrDesc &)> Customizer = {});
Expected<const InstrDesc &>
getOrCreateInstrDesc(const MCInst &MCI,
const SmallVector<Instrument *> &IVec);
@@ -123,7 +123,7 @@ class InstrBuilder {
LLVM_ABI Expected<std::unique_ptr<Instruction>>
createInstruction(const MCInst &MCI, const SmallVector<Instrument *> &IVec,
- std::function<void(InstrDesc &)> Customizer = {});
+ function_ref<void(InstrDesc &)> Customizer = {});
};
} // namespace mca
} // namespace llvm
diff --git a/llvm/lib/MCA/InstrBuilder.cpp b/llvm/lib/MCA/InstrBuilder.cpp
index 8b3e52a871f71..f65145b4203c0 100644
--- a/llvm/lib/MCA/InstrBuilder.cpp
+++ b/llvm/lib/MCA/InstrBuilder.cpp
@@ -559,7 +559,7 @@ Expected<unsigned> InstrBuilder::getVariantSchedClassID(const MCInst &MCI,
Expected<const InstrDesc &>
InstrBuilder::createInstrDescImpl(const MCInst &MCI,
const SmallVector<Instrument *> &IVec,
- std::function<void(InstrDesc &)> Customizer) {
+ function_ref<void(InstrDesc &)> Customizer) {
assert(STI.getSchedModel().hasInstrSchedModel() &&
"Itineraries are not yet supported!");
@@ -683,7 +683,7 @@ STATISTIC(NumVariantInst, "Number of MCInsts that doesn't have static Desc");
Expected<std::unique_ptr<Instruction>>
InstrBuilder::createInstruction(const MCInst &MCI,
const SmallVector<Instrument *> &IVec,
- std::function<void(InstrDesc &)> Customizer) {
+ function_ref<void(InstrDesc &)> Customizer) {
Expected<const InstrDesc &> DescOrErr =
Customizer ? createInstrDescImpl(MCI, IVec, Customizer)
: getOrCreateInstrDesc(MCI, IVec);
diff --git a/llvm/unittests/tools/llvm-mca/MCATestBase.h b/llvm/unittests/tools/llvm-mca/MCATestBase.h
index e991252cd3efd..c741d1f90c7f0 100644
--- a/llvm/unittests/tools/llvm-mca/MCATestBase.h
+++ b/llvm/unittests/tools/llvm-mca/MCATestBase.h
@@ -71,7 +71,7 @@ class MCATestBase : public ::testing::Test {
void SetUp() override;
- using Builder = std::function<Expected<std::unique_ptr<mca::Instruction>>(
+ using Builder = function_ref<Expected<std::unique_ptr<mca::Instruction>>(
mca::InstrBuilder &, const MCInst &,
const SmallVector<mca::Instrument *> &)>;
diff --git a/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp b/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp
index 8aa879b3e053d..668afd1a8d6be 100644
--- a/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp
+++ b/llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp
@@ -256,6 +256,7 @@ TEST_F(X86TestBase, TestInstructionCustomization) {
ID.MaxLatency = ExplicitLatency;
});
});
+ ASSERT_FALSE(bool(E)) << "Failed to run baseline";
auto *BaselineObj = BaselineResult.getObject("SummaryView");
auto V = BaselineObj->getInteger("TotalCycles");
ASSERT_TRUE(V);
More information about the llvm-commits
mailing list