[Mlir-commits] [mlir] [MLIR][LLVM] Add ProfileSummary module flag support (PR #138070)

Tobias Gysi llvmlistbot at llvm.org
Thu May 1 01:15:42 PDT 2025


================
@@ -554,13 +554,262 @@ static Attribute convertCGProfileModuleFlagValue(ModuleOp mlirModule,
   return ArrayAttr::get(mlirModule->getContext(), cgProfile);
 }
 
+static Attribute
+convertProfileSummaryModuleFlagValue(ModuleOp mlirModule,
+                                     const llvm::Module *llvmModule,
+                                     llvm::MDTuple *mdTuple) {
+  unsigned profileNumEntries = mdTuple->getNumOperands();
+  if (profileNumEntries < 8) {
+    emitWarning(mlirModule.getLoc())
+        << "expected at 8 entries in 'ProfileSummary': "
+        << diagMD(mdTuple, llvmModule);
+    return nullptr;
+  }
+
+  unsigned summayIdx = 0;
+
+  auto getMDTuple = [&](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;
+  };
+
+  auto getFormat = [&](const llvm::MDOperand &formatMD) -> StringAttr {
+    auto *tupleEntry = getMDTuple(formatMD);
+    if (!tupleEntry)
+      return nullptr;
+
+    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 nullptr;
+    }
+
+    llvm::MDString *valMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(1));
+    auto formatAttr = llvm::StringSwitch<std::string>(valMD->getString())
+                          .Case("SampleProfile", "SampleProfile")
+                          .Case("InstrProf", "InstrProf")
+                          .Case("CSInstrProf", "CSInstrProf")
+                          .Default("");
+    if (formatAttr.empty()) {
+      emitWarning(mlirModule.getLoc())
+          << "expected 'SampleProfile', 'InstrProf' or 'CSInstrProf' values, "
+             "but found: "
+          << diagMD(valMD, llvmModule);
+      return nullptr;
+    }
+
+    return StringAttr::get(mlirModule->getContext(), formatAttr);
+  };
+
+  auto getConstantMD = [&](const llvm::MDOperand &md, StringRef matchKey,
+                           bool optional =
+                               false) -> llvm::ConstantAsMetadata * {
+    auto *tupleEntry = getMDTuple(md);
+    if (!tupleEntry)
+      return nullptr;
+    llvm::MDString *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));
+  };
+
+  auto checkOptionalPosition = [&](const llvm::MDOperand &md,
+                                   StringRef matchKey) -> LogicalResult {
+    // Make sure we won't step over the bound of the array of summary entries.
+    // Since (non-optional) DetailedSummary always comes last, the next entry in
+    // the tuple operand array must exist.
+    if (summayIdx + 1 >= profileNumEntries) {
+      emitWarning(mlirModule.getLoc())
+          << "the last summary entry is '" << matchKey
+          << "', expected 'DetailedSummary': " << diagMD(md, llvmModule);
+      return failure();
+    }
+
+    return success();
+  };
+
+  auto getInt64Value = [&](const llvm::MDOperand &md, StringRef matchKey,
+                           uint64_t &val) {
+    auto *valMD = getConstantMD(md, matchKey);
+    if (!valMD)
+      return false;
+
+    if (auto *cstInt = dyn_cast<llvm::ConstantInt>(valMD->getValue())) {
+      val = cstInt->getZExtValue();
+      return true;
+    }
+
+    emitWarning(mlirModule.getLoc())
+        << "expected integer metadata value for key '" << matchKey
+        << "': " << diagMD(md, llvmModule);
+    return false;
+  };
+
+  auto getOptIntValue = [&](const llvm::MDOperand &md, StringRef matchKey,
+                            IntegerAttr &attr) -> LogicalResult {
+    if (!getConstantMD(md, matchKey, /*optional=*/true))
+      return success();
+    if (checkOptionalPosition(md, matchKey).failed())
+      return failure();
+    uint64_t val = 0;
+    if (!getInt64Value(md, matchKey, val))
+      return failure();
+    attr =
+        IntegerAttr::get(IntegerType::get(mlirModule->getContext(), 64), val);
----------------
gysit wrote:

Looks like the optional values are typed. Then I would go with std::optional<int64_t> in the attribute. Similarly below for the double.

https://github.com/llvm/llvm-project/pull/138070


More information about the Mlir-commits mailing list