[Mlir-commits] [mlir] 9b76a30 - [mlir][llvm] Support importing magic globals
Tobias Gysi
llvmlistbot at llvm.org
Wed Jan 4 02:26:47 PST 2023
Author: Christian Ulmann
Date: 2023-01-04T11:25:55+01:00
New Revision: 9b76a3020e9594ade61068f8091661d4142702f2
URL: https://github.com/llvm/llvm-project/commit/9b76a3020e9594ade61068f8091661d4142702f2
DIFF: https://github.com/llvm/llvm-project/commit/9b76a3020e9594ade61068f8091661d4142702f2.diff
LOG: [mlir][llvm] Support importing magic globals
This commit adds support for importing the magic globals "global_ctors"
and "global_dtors" from LLVM IR to the LLVM IR dialect. The import
fails when these globals have a non-null data pointer, as this can
currently not be represented in the corresponding MLIR operations.
Reviewed By: gysit
Differential Revision: https://reviews.llvm.org/D140877
Added:
Modified:
mlir/include/mlir/Target/LLVMIR/ModuleImport.h
mlir/lib/Target/LLVMIR/ModuleImport.cpp
mlir/test/Target/LLVMIR/Import/global-variables.ll
mlir/test/Target/LLVMIR/Import/import-failure.ll
Removed:
################################################################################
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 27e2b297e8f31..2493cbde3d4f3 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -218,6 +218,9 @@ class ModuleImport {
/// function entry block.
FailureOr<Value> convertConstantExpr(llvm::Constant *constant);
+ /// Imports the magic globals "global_ctors" and "global_dtors".
+ LogicalResult convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar);
+
/// Builder pointing at where the next instruction should be generated.
OpBuilder builder;
/// Block to insert the next constant into.
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 750e967eb956a..1c0ac6b4f7496 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -48,6 +48,16 @@ static std::string diag(llvm::Value &value) {
return os.str();
}
+/// Returns the name of the global_ctors global variables.
+static constexpr StringRef getGlobalCtorsVarName() {
+ return "llvm.global_ctors";
+}
+
+/// Returns the name of the global_dtors global variables.
+static constexpr StringRef getGlobalDtorsVarName() {
+ return "llvm.global_dtors";
+}
+
/// Creates an attribute containing ABI and preferred alignment numbers parsed
/// a string. The string may be either "abi:preferred" or just "abi". In the
/// latter case, the preferred alignment is considered equal to ABI alignment.
@@ -319,9 +329,19 @@ ModuleImport::ModuleImport(ModuleOp mlirModule,
}
LogicalResult ModuleImport::convertGlobals() {
- for (llvm::GlobalVariable &globalVar : llvmModule->globals())
+ for (llvm::GlobalVariable &globalVar : llvmModule->globals()) {
+ if (globalVar.getName() == getGlobalCtorsVarName() ||
+ globalVar.getName() == getGlobalDtorsVarName()) {
+ if (failed(convertGlobalCtorsAndDtors(&globalVar))) {
+ return emitError(mlirModule.getLoc())
+ << "unhandled global variable " << diag(globalVar);
+ }
+ continue;
+ }
+
if (!processGlobal(&globalVar))
return failure();
+ }
return success();
}
@@ -563,6 +583,54 @@ GlobalOp ModuleImport::processGlobal(llvm::GlobalVariable *globalVar) {
return globals[globalVar] = globalOp;
}
+LogicalResult
+ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
+ if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
+ return failure();
+ auto *initializer =
+ dyn_cast<llvm::ConstantArray>(globalVar->getInitializer());
+ if (!initializer)
+ return failure();
+
+ SmallVector<Attribute> funcs;
+ SmallVector<int32_t> priorities;
+ for (llvm::Value *operand : initializer->operands()) {
+ auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
+ if (!aggregate || aggregate->getNumOperands() != 3)
+ return failure();
+
+ auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
+ auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
+ auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
+ if (!priority || !func || !data)
+ return failure();
+
+ // GlobalCtorsOps and GlobalDtorsOps do not support non-null data fields.
+ if (!data->isNullValue())
+ return failure();
+
+ funcs.push_back(FlatSymbolRefAttr::get(context, func->getName()));
+ priorities.push_back(priority->getValue().getZExtValue());
+ }
+
+ OpBuilder::InsertionGuard guard(builder);
+ if (!globalInsertionOp)
+ builder.setInsertionPointToStart(mlirModule.getBody());
+ else
+ builder.setInsertionPointAfter(globalInsertionOp);
+
+ if (globalVar->getName() == getGlobalCtorsVarName()) {
+ globalInsertionOp = builder.create<LLVM::GlobalCtorsOp>(
+ mlirModule.getLoc(), builder.getArrayAttr(funcs),
+ builder.getI32ArrayAttr(priorities));
+ return success();
+ }
+ globalInsertionOp = builder.create<LLVM::GlobalDtorsOp>(
+ mlirModule.getLoc(), builder.getArrayAttr(funcs),
+ builder.getI32ArrayAttr(priorities));
+ return success();
+}
+
SetVector<llvm::Constant *>
ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
// Traverse the constant dependencies in post order.
diff --git a/mlir/test/Target/LLVMIR/Import/global-variables.ll b/mlir/test/Target/LLVMIR/Import/global-variables.ll
index 9f6b426f4e8e2..3bf37da19b01f 100644
--- a/mlir/test/Target/LLVMIR/Import/global-variables.ll
+++ b/mlir/test/Target/LLVMIR/Import/global-variables.ll
@@ -174,3 +174,18 @@
; CHECK-SAME: (dense<[{{\[}}[1, 2], [3, 4]]]> : vector<1x2x2xi32>)
; CHECK-SAME: {addr_space = 0 : i32, dso_local} : !llvm.array<1 x array<2 x vector<2xi32>>>
@nested_array_vector = internal constant [1 x [2 x <2 x i32>]] [[2 x <2 x i32>] [<2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4>]]
+
+; // -----
+
+; CHECK: llvm.mlir.global_ctors {ctors = [@foo, @bar], priorities = [0 : i32, 42 : i32]}
+; CHECK: llvm.mlir.global_dtors {dtors = [@foo], priorities = [0 : i32]}
+ at llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @foo, ptr null }, { i32, ptr, ptr } { i32 42, ptr @bar, ptr null }]
+ at llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @foo, ptr null }]
+
+define void @foo() {
+ ret void
+}
+
+define void @bar() {
+ ret void
+}
diff --git a/mlir/test/Target/LLVMIR/Import/import-failure.ll b/mlir/test/Target/LLVMIR/Import/import-failure.ll
index 740f055e1eaac..cba4173c829ff 100644
--- a/mlir/test/Target/LLVMIR/Import/import-failure.ll
+++ b/mlir/test/Target/LLVMIR/Import/import-failure.ll
@@ -67,3 +67,43 @@ define void @dropped_instruction(i64 %arg1) {
!3 = !DILocalVariable(scope: !4, name: "arg", file: !2, line: 1, arg: 1, align: 32);
!4 = distinct !DISubprogram(name: "intrinsic", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1)
!5 = !DILocation(line: 1, column: 2, scope: !4)
+
+; // -----
+
+; global_ctors requires the appending linkage type.
+; CHECK: error: unhandled global variable @llvm.global_ctors
+ at llvm.global_ctors = global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @foo, ptr null }]
+
+define void @foo() {
+ ret void
+}
+
+; // -----
+
+; global_dtors with non-null data fields cannot be represented in MLIR.
+; CHECK: error: unhandled global variable @llvm.global_dtors
+ at llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @foo, ptr @foo }]
+
+define void @foo() {
+ ret void
+}
+
+; // -----
+
+; global_ctors without a data field should not be imported.
+; CHECK: error: unhandled global variable @llvm.global_ctors
+ at llvm.global_ctors = appending global [1 x { i32, ptr }] [{ i32, ptr } { i32 0, ptr @foo }]
+
+define void @foo() {
+ ret void
+}
+
+; // -----
+
+; global_dtors with a wrong argument order should not be imported.
+; CHECK: error: unhandled global variable @llvm.global_dtors
+ at llvm.global_dtors = appending global [1 x { ptr, i32, ptr }] [{ ptr, i32, ptr } { ptr @foo, i32 0, ptr null }]
+
+define void @foo() {
+ ret void
+}
More information about the Mlir-commits
mailing list