[Mlir-commits] [mlir] [MLIR][LLVM] Allow importing of nameless globals (PR #101918)

Ivan R. Ivanov llvmlistbot at llvm.org
Mon Aug 5 02:21:09 PDT 2024


https://github.com/ivanradanov updated https://github.com/llvm/llvm-project/pull/101918

>From 474eed0ac72f6a10799f9efd72b2c8bb7f19c1eb Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Mon, 5 Aug 2024 11:14:50 +0900
Subject: [PATCH 1/7] [MLIR][LLVM] Allow importing of nameless globals

LLVM allows nameless globals for private global variables whereas in
MLIR globals must be addressed using symbols. We attach symbols to
nameless globals in order to enable their import.
---
 .../include/mlir/Target/LLVMIR/ModuleImport.h |  3 +++
 mlir/lib/Target/LLVMIR/ModuleImport.cpp       | 21 +++++++++++++++++--
 .../Target/LLVMIR/Import/global-variables.ll  | 15 ++++++++++++-
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 04d098d38155b..2667530963109 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -19,6 +19,7 @@
 #include "mlir/Target/LLVMIR/Import.h"
 #include "mlir/Target/LLVMIR/LLVMImportInterface.h"
 #include "mlir/Target/LLVMIR/TypeFromLLVM.h"
+#include "llvm/IR/GlobalVariable.h"
 
 namespace llvm {
 class BasicBlock;
@@ -367,6 +368,8 @@ class ModuleImport {
   ModuleOp mlirModule;
   /// The LLVM module being imported.
   std::unique_ptr<llvm::Module> llvmModule;
+  /// Nameless globals
+  DenseMap<llvm::GlobalVariable *, FlatSymbolRefAttr> namelessGlobals;
 
   /// A dialect interface collection used for dispatching the import to specific
   /// dialects.
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 8b40b7b2df6c7..f84ad30a546ea 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "mlir/Target/LLVMIR/ModuleImport.h"
+#include "mlir/IR/BuiltinAttributes.h"
 #include "mlir/Target/LLVMIR/Import.h"
 
 #include "AttrKindDetail.h"
@@ -73,6 +74,11 @@ static constexpr StringRef getGlobalCtorsVarName() {
   return "llvm.global_ctors";
 }
 
+/// Prefix used for symbols of nameless llvm globals.
+static constexpr StringRef getNamelessGlobalPrefix() {
+  return "mlir.llvm.nameless_global.";
+}
+
 /// Returns the name of the global_dtors global variables.
 static constexpr StringRef getGlobalDtorsVarName() {
   return "llvm.global_dtors";
@@ -884,9 +890,15 @@ LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
     globalExpressionAttr =
         debugImporter->translateGlobalVariableExpression(globalExpressions[0]);
 
+  std::string globalName = globalVar->getName().str();
+  if (globalName == "") {
+    globalName = getNamelessGlobalPrefix().str() +
+                 std::to_string(namelessGlobals.size());
+    namelessGlobals[globalVar] = FlatSymbolRefAttr::get(context, globalName);
+  }
   GlobalOp globalOp = builder.create<GlobalOp>(
       mlirModule.getLoc(), type, globalVar->isConstant(),
-      convertLinkageFromLLVM(globalVar->getLinkage()), globalVar->getName(),
+      convertLinkageFromLLVM(globalVar->getLinkage()), globalName.c_str(),
       valueAttr, alignment, /*addr_space=*/globalVar->getAddressSpace(),
       /*dso_local=*/globalVar->isDSOLocal(),
       /*thread_local=*/globalVar->isThreadLocal(), /*comdat=*/SymbolRefAttr(),
@@ -1061,7 +1073,12 @@ FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
   // Convert global variable accesses.
   if (auto *globalVar = dyn_cast<llvm::GlobalVariable>(constant)) {
     Type type = convertType(globalVar->getType());
-    auto symbolRef = FlatSymbolRefAttr::get(context, globalVar->getName());
+    StringRef globalName = globalVar->getName();
+    FlatSymbolRefAttr symbolRef;
+    if (globalName == "")
+      symbolRef = namelessGlobals[globalVar];
+    else
+      symbolRef = FlatSymbolRefAttr::get(context, globalName);
     return builder.create<AddressOfOp>(loc, type, symbolRef).getResult();
   }
 
diff --git a/mlir/test/Target/LLVMIR/Import/global-variables.ll b/mlir/test/Target/LLVMIR/Import/global-variables.ll
index 902f77bd7e6cb..d8c33e311c626 100644
--- a/mlir/test/Target/LLVMIR/Import/global-variables.ll
+++ b/mlir/test/Target/LLVMIR/Import/global-variables.ll
@@ -280,7 +280,20 @@ define void @bar() {
 ; CHECK-DAG: #[[GLOBAL_VAR:.*]] = #llvm.di_global_variable<file = #[[FILE]], line = 268, type = #[[COMPOSITE_TYPE]], isLocalToUnit = true, isDefined = true>
 ; CHECK-DAG: #[[GLOBAL_VAR_EXPR:.*]] = #llvm.di_global_variable_expression<var = #[[GLOBAL_VAR]], expr = <>>
 
-; CHECK-DAG: llvm.mlir.global external constant @".str.1"() {addr_space = 0 : i32, dbg_expr = #[[GLOBAL_VAR_EXPR]]}
+; CHECK:  llvm.mlir.global private unnamed_addr constant @mlir.llvm.nameless_global.0("0\00") {addr_space = 0 : i32, dso_local}
+; CHECK:  llvm.mlir.global private unnamed_addr constant @mlir.llvm.nameless_global.1("1\00") {addr_space = 0 : i32, dso_local}
+;
+; CHECK:  llvm.mlir.global internal constant @zero() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+; CHECK:    llvm.mlir.addressof @mlir.llvm.nameless_global.0 : !llvm.ptr
+; CHECK:  llvm.mlir.global internal constant @one() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+; CHECK:    llvm.mlir.addressof @mlir.llvm.nameless_global.1 : !llvm.ptr
+
+; CHECK: llvm.mlir.global external constant @".str.1"() {addr_space = 0 : i32, dbg_expr = #[[GLOBAL_VAR_EXPR]]}
+
+ at 0 = private unnamed_addr constant [2 x i8] c"0\00"
+ at 1 = private unnamed_addr constant [2 x i8] c"1\00"
+ at zero = internal constant ptr @0
+ at one = internal constant ptr @1
 
 @.str.1 = external constant [10 x i8], !dbg !0
 

>From 3f771867f3a06ca694946778203a9df3ab1c4de7 Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Mon, 5 Aug 2024 13:00:05 +0900
Subject: [PATCH 2/7] Update mlir/include/mlir/Target/LLVMIR/ModuleImport.h

Co-authored-by: Christian Ulmann <christianulmann at gmail.com>
---
 mlir/include/mlir/Target/LLVMIR/ModuleImport.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 2667530963109..8af3ee0c4809f 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -368,7 +368,7 @@ class ModuleImport {
   ModuleOp mlirModule;
   /// The LLVM module being imported.
   std::unique_ptr<llvm::Module> llvmModule;
-  /// Nameless globals
+  /// Nameless globals.
   DenseMap<llvm::GlobalVariable *, FlatSymbolRefAttr> namelessGlobals;
 
   /// A dialect interface collection used for dispatching the import to specific

>From 4a8ebbe54c188b19ad3ac99ed541894bac7b1b0a Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Mon, 5 Aug 2024 13:00:50 +0900
Subject: [PATCH 3/7] Update mlir/lib/Target/LLVMIR/ModuleImport.cpp

Co-authored-by: Christian Ulmann <christianulmann at gmail.com>
---
 mlir/lib/Target/LLVMIR/ModuleImport.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index f84ad30a546ea..693d93245ff16 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1075,7 +1075,7 @@ FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
     Type type = convertType(globalVar->getType());
     StringRef globalName = globalVar->getName();
     FlatSymbolRefAttr symbolRef;
-    if (globalName == "")
+    if (globalName.empty())
       symbolRef = namelessGlobals[globalVar];
     else
       symbolRef = FlatSymbolRefAttr::get(context, globalName);

>From 9ce7ee18c661963b3f382d40537f7dca6544e716 Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Mon, 5 Aug 2024 13:01:07 +0900
Subject: [PATCH 4/7] Update mlir/lib/Target/LLVMIR/ModuleImport.cpp

Co-authored-by: Christian Ulmann <christianulmann at gmail.com>
---
 mlir/lib/Target/LLVMIR/ModuleImport.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 693d93245ff16..7c9366a2e8265 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -891,7 +891,7 @@ LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
         debugImporter->translateGlobalVariableExpression(globalExpressions[0]);
 
   std::string globalName = globalVar->getName().str();
-  if (globalName == "") {
+  if (globalName.empty()) {
     globalName = getNamelessGlobalPrefix().str() +
                  std::to_string(namelessGlobals.size());
     namelessGlobals[globalVar] = FlatSymbolRefAttr::get(context, globalName);

>From 855845c4aa6f678cd17edb2c57df4dd19080fd82 Mon Sep 17 00:00:00 2001
From: "Ivan R. Ivanov" <ivanov.i.aa at m.titech.ac.jp>
Date: Mon, 5 Aug 2024 13:01:20 +0900
Subject: [PATCH 5/7] Update mlir/test/Target/LLVMIR/Import/global-variables.ll

Co-authored-by: Christian Ulmann <christianulmann at gmail.com>
---
 mlir/test/Target/LLVMIR/Import/global-variables.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/test/Target/LLVMIR/Import/global-variables.ll b/mlir/test/Target/LLVMIR/Import/global-variables.ll
index d8c33e311c626..2ed0245a13cf2 100644
--- a/mlir/test/Target/LLVMIR/Import/global-variables.ll
+++ b/mlir/test/Target/LLVMIR/Import/global-variables.ll
@@ -280,7 +280,7 @@ define void @bar() {
 ; CHECK-DAG: #[[GLOBAL_VAR:.*]] = #llvm.di_global_variable<file = #[[FILE]], line = 268, type = #[[COMPOSITE_TYPE]], isLocalToUnit = true, isDefined = true>
 ; CHECK-DAG: #[[GLOBAL_VAR_EXPR:.*]] = #llvm.di_global_variable_expression<var = #[[GLOBAL_VAR]], expr = <>>
 
-; CHECK:  llvm.mlir.global private unnamed_addr constant @mlir.llvm.nameless_global.0("0\00") {addr_space = 0 : i32, dso_local}
+; CHECK:  llvm.mlir.global private unnamed_addr constant @mlir.llvm.nameless_global.0("0\00")
 ; CHECK:  llvm.mlir.global private unnamed_addr constant @mlir.llvm.nameless_global.1("1\00") {addr_space = 0 : i32, dso_local}
 ;
 ; CHECK:  llvm.mlir.global internal constant @zero() {addr_space = 0 : i32, dso_local} : !llvm.ptr {

>From 6906308f0a74ccf803bb88479de3fb03b1a03424 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Mon, 5 Aug 2024 15:32:21 +0900
Subject: [PATCH 6/7] Implement suggested changes

---
 mlir/include/mlir/Target/LLVMIR/ModuleImport.h | 1 -
 mlir/lib/Target/LLVMIR/ModuleImport.cpp        | 4 +++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 8af3ee0c4809f..a1fc9179bb34a 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -19,7 +19,6 @@
 #include "mlir/Target/LLVMIR/Import.h"
 #include "mlir/Target/LLVMIR/LLVMImportInterface.h"
 #include "mlir/Target/LLVMIR/TypeFromLLVM.h"
-#include "llvm/IR/GlobalVariable.h"
 
 namespace llvm {
 class BasicBlock;
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 7c9366a2e8265..69fc1c0dcd8d2 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -890,6 +890,8 @@ LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
     globalExpressionAttr =
         debugImporter->translateGlobalVariableExpression(globalExpressions[0]);
 
+  // Workaround to support LLVM's nameless globals. MLIR, in contrast to LLVM,
+  // always requires a symbol name.
   std::string globalName = globalVar->getName().str();
   if (globalName.empty()) {
     globalName = getNamelessGlobalPrefix().str() +
@@ -898,7 +900,7 @@ LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
   }
   GlobalOp globalOp = builder.create<GlobalOp>(
       mlirModule.getLoc(), type, globalVar->isConstant(),
-      convertLinkageFromLLVM(globalVar->getLinkage()), globalName.c_str(),
+      convertLinkageFromLLVM(globalVar->getLinkage()), StringRef(globalName),
       valueAttr, alignment, /*addr_space=*/globalVar->getAddressSpace(),
       /*dso_local=*/globalVar->isDSOLocal(),
       /*thread_local=*/globalVar->isThreadLocal(), /*comdat=*/SymbolRefAttr(),

>From 6ddc6a479dbb6e73abba8b7e8a81140cc3080354 Mon Sep 17 00:00:00 2001
From: Ivan Radanov Ivanov <ivanov.i.aa at m.titech.ac.jp>
Date: Mon, 5 Aug 2024 18:20:49 +0900
Subject: [PATCH 7/7] Avoid symbol clashes

---
 mlir/include/mlir/Target/LLVMIR/ModuleImport.h     | 2 ++
 mlir/lib/Target/LLVMIR/ModuleImport.cpp            | 7 +++++--
 mlir/test/Target/LLVMIR/Import/global-variables.ll | 8 ++++++--
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index a1fc9179bb34a..b19cd0b8e18d4 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -369,6 +369,8 @@ class ModuleImport {
   std::unique_ptr<llvm::Module> llvmModule;
   /// Nameless globals.
   DenseMap<llvm::GlobalVariable *, FlatSymbolRefAttr> namelessGlobals;
+  /// Counter used to assign a unique ID to each nameless global.
+  unsigned namelessGlobalId = 0;
 
   /// A dialect interface collection used for dispatching the import to specific
   /// dialects.
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 69fc1c0dcd8d2..f938da4ddc2b3 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -894,8 +894,11 @@ LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
   // always requires a symbol name.
   std::string globalName = globalVar->getName().str();
   if (globalName.empty()) {
-    globalName = getNamelessGlobalPrefix().str() +
-                 std::to_string(namelessGlobals.size());
+    // Make sure the symbol name does not clash with an existing symbol.
+    do {
+      globalName =
+          getNamelessGlobalPrefix().str() + std::to_string(namelessGlobalId++);
+    } while (llvmModule->getNamedValue(globalName));
     namelessGlobals[globalVar] = FlatSymbolRefAttr::get(context, globalName);
   }
   GlobalOp globalOp = builder.create<GlobalOp>(
diff --git a/mlir/test/Target/LLVMIR/Import/global-variables.ll b/mlir/test/Target/LLVMIR/Import/global-variables.ll
index 2ed0245a13cf2..71a38c18298f1 100644
--- a/mlir/test/Target/LLVMIR/Import/global-variables.ll
+++ b/mlir/test/Target/LLVMIR/Import/global-variables.ll
@@ -281,12 +281,13 @@ define void @bar() {
 ; CHECK-DAG: #[[GLOBAL_VAR_EXPR:.*]] = #llvm.di_global_variable_expression<var = #[[GLOBAL_VAR]], expr = <>>
 
 ; CHECK:  llvm.mlir.global private unnamed_addr constant @mlir.llvm.nameless_global.0("0\00")
-; CHECK:  llvm.mlir.global private unnamed_addr constant @mlir.llvm.nameless_global.1("1\00") {addr_space = 0 : i32, dso_local}
+; We skip over @mlir.llvm.nameless_global.1 and 2 because they exist
+; CHECK:  llvm.mlir.global private unnamed_addr constant @mlir.llvm.nameless_global.3("1\00")
 ;
 ; CHECK:  llvm.mlir.global internal constant @zero() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
 ; CHECK:    llvm.mlir.addressof @mlir.llvm.nameless_global.0 : !llvm.ptr
 ; CHECK:  llvm.mlir.global internal constant @one() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
-; CHECK:    llvm.mlir.addressof @mlir.llvm.nameless_global.1 : !llvm.ptr
+; CHECK:    llvm.mlir.addressof @mlir.llvm.nameless_global.3 : !llvm.ptr
 
 ; CHECK: llvm.mlir.global external constant @".str.1"() {addr_space = 0 : i32, dbg_expr = #[[GLOBAL_VAR_EXPR]]}
 
@@ -295,6 +296,9 @@ define void @bar() {
 @zero = internal constant ptr @0
 @one = internal constant ptr @1
 
+@"mlir.llvm.nameless_global.1" = external constant [10 x i8], !dbg !0
+declare void @"mlir.llvm.nameless_global.2"()
+
 @.str.1 = external constant [10 x i8], !dbg !0
 
 !llvm.module.flags = !{!7}



More information about the Mlir-commits mailing list