[Mlir-commits] [mlir] [MLIR][LLVM] Add ProfileSummary module flag support (PR #138070)
Christian Ulmann
llvmlistbot at llvm.org
Sun May 4 22:58:27 PDT 2025
================
@@ -554,13 +555,289 @@ static Attribute convertCGProfileModuleFlagValue(ModuleOp mlirModule,
return ArrayAttr::get(mlirModule->getContext(), cgProfile);
}
+/// Extract a two element `MDTuple` from a `MDOperand`. Emit a warning in case
+/// something else is found.
+static llvm::MDTuple *getTwoElementMDTuple(ModuleOp mlirModule,
+ const llvm::Module *llvmModule,
+ const llvm::MDOperand &md) {
+ auto *tupleEntry = dyn_cast_or_null<llvm::MDTuple>(md);
+ if (!tupleEntry || tupleEntry->getNumOperands() != 2)
+ emitWarning(mlirModule.getLoc())
+ << "expected 2-element tuple metadata: " << diagMD(md, llvmModule);
+ return tupleEntry;
+}
+
+/// Extract a constant metadata value from a two element tuple (<key, value>).
+/// Return nullptr if requirements are not met. A warning is emitted if the
+/// `matchKey` is different from the tuple's key.
+static llvm::ConstantAsMetadata *getConstantMDFromKeyValueTuple(
+ ModuleOp mlirModule, const llvm::Module *llvmModule,
+ const llvm::MDOperand &md, StringRef matchKey, bool optional = false) {
+ llvm::MDTuple *tupleEntry = getTwoElementMDTuple(mlirModule, llvmModule, md);
+ if (!tupleEntry)
+ return nullptr;
+ auto *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
+ if (!keyMD || keyMD->getString() != matchKey) {
+ if (!optional)
+ emitWarning(mlirModule.getLoc())
+ << "expected '" << matchKey << "' key, but found: "
+ << diagMD(tupleEntry->getOperand(0), llvmModule);
+ return nullptr;
+ }
+
+ return dyn_cast<llvm::ConstantAsMetadata>(tupleEntry->getOperand(1));
+}
+
+/// Extract an integer value from a two element tuple (<key, value>).
+/// Fail if requirements are not met. A warning is emitted if the
+/// found value isn't a LLVM constant integer.
+static FailureOr<uint64_t>
+convertInt64FromKeyValueTuple(ModuleOp mlirModule,
+ const llvm::Module *llvmModule,
+ const llvm::MDOperand &md, StringRef matchKey) {
+ auto *valMD =
+ getConstantMDFromKeyValueTuple(mlirModule, llvmModule, md, matchKey);
+ if (!valMD)
+ return failure();
+
+ if (auto *cstInt = dyn_cast<llvm::ConstantInt>(valMD->getValue()))
+ return cstInt->getZExtValue();
+
+ emitWarning(mlirModule.getLoc())
+ << "expected integer metadata value for key '" << matchKey
+ << "': " << diagMD(md, llvmModule);
+ return failure();
+}
+
+static std::optional<ProfileSummaryFormatKind>
+convertProfileSummaryFormat(ModuleOp mlirModule, const llvm::Module *llvmModule,
+ const llvm::MDOperand &formatMD) {
+ auto *tupleEntry = getTwoElementMDTuple(mlirModule, llvmModule, formatMD);
+ if (!tupleEntry)
+ return std::nullopt;
+
+ llvm::MDString *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
+ if (!keyMD || keyMD->getString() != "ProfileFormat") {
+ emitWarning(mlirModule.getLoc())
+ << "expected 'ProfileFormat' key: "
+ << diagMD(tupleEntry->getOperand(0), llvmModule);
+ return std::nullopt;
+ }
+
+ llvm::MDString *valMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(1));
+ std::optional<ProfileSummaryFormatKind> fmtKind =
+ symbolizeProfileSummaryFormatKind(valMD->getString());
+ if (!fmtKind) {
+ emitWarning(mlirModule.getLoc())
+ << "expected 'SampleProfile', 'InstrProf' or 'CSInstrProf' values, "
+ "but found: "
+ << diagMD(valMD, llvmModule);
+ return std::nullopt;
+ }
+
+ return fmtKind;
+}
+
+static FailureOr<SmallVector<ModuleFlagProfileSummaryDetailedAttr>>
+convertProfileSummaryDetailed(ModuleOp mlirModule,
+ const llvm::Module *llvmModule,
+ const llvm::MDOperand &summaryMD) {
+ auto *tupleEntry = getTwoElementMDTuple(mlirModule, llvmModule, summaryMD);
+ if (!tupleEntry)
+ return failure();
+
+ llvm::MDString *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
+ if (!keyMD || keyMD->getString() != "DetailedSummary") {
+ emitWarning(mlirModule.getLoc())
+ << "expected 'DetailedSummary' key: "
+ << diagMD(tupleEntry->getOperand(0), llvmModule);
+ return failure();
+ }
+
+ llvm::MDTuple *entriesMD = dyn_cast<llvm::MDTuple>(tupleEntry->getOperand(1));
+ if (!entriesMD) {
+ emitWarning(mlirModule.getLoc())
+ << "expected tuple value for 'DetailedSummary' key: "
+ << diagMD(tupleEntry->getOperand(1), llvmModule);
+ return failure();
+ }
+
+ SmallVector<ModuleFlagProfileSummaryDetailedAttr> detailedSummary;
+ for (auto &&entry : entriesMD->operands()) {
+ llvm::MDTuple *entryMD = dyn_cast<llvm::MDTuple>(entry);
+ if (!entryMD || entryMD->getNumOperands() != 3) {
+ emitWarning(mlirModule.getLoc())
+ << "'DetailedSummary' entry expects 3 operands: "
+ << diagMD(entry, llvmModule);
+ return failure();
+ }
+ llvm::ConstantAsMetadata *op0 =
----------------
Dinistro wrote:
Nit: Here `auto` would be preferable, due to having the types on the RHS.
https://github.com/llvm/llvm-project/pull/138070
More information about the Mlir-commits
mailing list