https://github.com/Lancern created 
https://github.com/llvm/llvm-project/pull/146261

This patch adds the `#cir.opt_info` attribute which holds module-level 
optimization information.

>From c1f884577af1d55cb7cc9b65276e43bd96b82378 Mon Sep 17 00:00:00 2001
From: Sirui Mu <msrlanc...@gmail.com>
Date: Sun, 29 Jun 2025 15:25:10 +0800
Subject: [PATCH] [CIR] Add OptInfo attribute

---
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  | 48 +++++++++++++++++++
 .../clang/CIR/Dialect/IR/CIRDialect.td        |  1 +
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        |  6 +++
 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp         | 15 ++++++
 clang/test/CIR/CodeGen/opt-info-attr.cpp      | 22 +++++++++
 5 files changed, 92 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/opt-info-attr.cpp

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 9a6560519eec4..c6dd753950859 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -65,6 +65,54 @@ class CIRUnitAttr<string name, string attrMnemonic, 
list<Trait> traits = []>
   let isOptional = 1;
 }
 
+//===----------------------------------------------------------------------===//
+// OptInfoAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_OptInfoAttr : CIR_Attr<"OptInfo", "opt_info"> {
+  let summary =
+    "A module-level attribute that holds the optimization information";
+  let description = [{
+    The `#cir.opt_info` attribute holds optimization related information. For
+    now this attribute is a module-level attribute that gets attached to the
+    module operation during CIRGen.
+
+    The `level` parameter gives the optimization level. It must be an integer
+    between 0 and 3, inclusive. It corresponds to the `OptimizationLevel` field
+    within the `clang::CodeGenOptions` structure.
+
+    The `size` parameter gives the code size optimization level. It must be an
+    integer between 0 and 2, inclusive. It corresponds to the `OptimizeSize`
+    field within the `clang::CodeGenOptions` structure.
+
+    The `level` and `size` parameters correspond to the optimization level
+    command line options passed to clang driver. The table below lists the
+    current correspondance relationship:
+
+    | Flag             | `level` | `size` |
+    |------------------|---------|--------|
+    | `-O0` or nothing | 0       | 0      |
+    | `-O1`            | 1       | 0      |
+    | `-O2`            | 2       | 0      |
+    | `-O3`            | 3       | 0      |
+    | `-Os`            | 2       | 1      |
+    | `-Oz`            | 2       | 2      |
+
+    Examples:
+
+    ```mlir
+    #cir.opt_info<level = 2, size = 0>  // -O2
+    ```
+  }];
+
+  let parameters = (ins "unsigned":$level, "unsigned":$size);
+
+  let assemblyFormat = [{
+    `<` struct(params) `>`
+  }];
+  let genVerifyDecl = 1;
+}
+
 
//===----------------------------------------------------------------------===//
 // BoolAttr
 
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td 
b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
index 52e32eedf774d..d77ed53aa93a1 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
@@ -36,6 +36,7 @@ def CIR_Dialect : Dialect {
 
   let extraClassDeclaration = [{
     static llvm::StringRef getTripleAttrName() { return "cir.triple"; }
+    static llvm::StringRef getOptInfoAttrName() { return "cir.opt_info"; }
 
     void registerAttributes();
     void registerTypes();
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 7198b231d934b..c1434ee697f4c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -104,6 +104,12 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
 
   theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
                      builder.getStringAttr(getTriple().str()));
+
+  if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
+    theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
+                       cir::OptInfoAttr::get(&mlirContext,
+                                             cgo.OptimizationLevel,
+                                             cgo.OptimizeSize));
 }
 
 CIRGenModule::~CIRGenModule() = default;
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp 
b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index 29a9a815c31a1..0f84ffa4bf131 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -55,6 +55,21 @@ void CIRDialect::printAttribute(Attribute attr, 
DialectAsmPrinter &os) const {
     llvm_unreachable("unexpected CIR type kind");
 }
 
+//===----------------------------------------------------------------------===//
+// OptInfoAttr definitions
+//===----------------------------------------------------------------------===//
+
+LogicalResult OptInfoAttr::verify(function_ref<InFlightDiagnostic()> emitError,
+                                  unsigned level, unsigned size) {
+  if (level > 3)
+    return emitError()
+           << "optimization level must be between 0 and 3 inclusive";
+  if (size > 2)
+    return emitError()
+           << "size optimization level must be between 0 and 2 inclusive";
+  return success();
+}
+
 
//===----------------------------------------------------------------------===//
 // ConstPtrAttr definitions
 
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CIR/CodeGen/opt-info-attr.cpp 
b/clang/test/CIR/CodeGen/opt-info-attr.cpp
new file mode 100644
index 0000000000000..444286b8db8a9
--- /dev/null
+++ b/clang/test/CIR/CodeGen/opt-info-attr.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CHECK-O0
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -O1 -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CHECK-O1
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -O2 -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CHECK-O2
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -O3 -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CHECK-O3
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Os -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CHECK-Os
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Oz -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CHECK-Oz
+
+void f() {}
+
+// CHECK-O0: module attributes
+// CHECK-O0-NOT: cir.opt_info
+// CHECK-O1: module attributes {{.+}}cir.opt_info = #cir.opt_info<level = 1, 
size = 0>{{.+}}
+// CHECK-O2: module attributes {{.+}}cir.opt_info = #cir.opt_info<level = 2, 
size = 0>{{.+}}
+// CHECK-O3: module attributes {{.+}}cir.opt_info = #cir.opt_info<level = 3, 
size = 0>{{.+}}
+// CHECK-Os: module attributes {{.+}}cir.opt_info = #cir.opt_info<level = 2, 
size = 1>{{.+}}
+// CHECK-Oz: module attributes {{.+}}cir.opt_info = #cir.opt_info<level = 2, 
size = 2>{{.+}}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to