Skip to content

Commit 0fde03c

Browse files
committed
[mlir][llvm] Modernize the import of LLVM IR globals.
Return failure if the import of a global variable fails and add a test case to check the emitted error message. Additionally, convert the globals in iteration order and do not process them recursively when translating a constant expression referencing it. Additionally, use the module location rather unknown location. Reviewed By: Dinistro Differential Revision: https://reviews.llvm.org/D140966
1 parent d3d7ba1 commit 0fde03c

File tree

4 files changed

+44
-31
lines changed

4 files changed

+44
-31
lines changed

mlir/include/mlir/Target/LLVMIR/ModuleImport.h

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ class ModuleImport {
7575
/// Stores a mapping between an LLVM instruction and the imported MLIR
7676
/// operation if the operation returns no result. Asserts if the operation
7777
/// returns a result and should be added to valueMapping instead.
78-
void mapNoResultOp(llvm::Instruction *inst, Operation *mlir) {
79-
mapNoResultOp(inst) = mlir;
78+
void mapNoResultOp(llvm::Instruction *llvm, Operation *mlir) {
79+
mapNoResultOp(llvm) = mlir;
8080
}
8181

8282
/// Provides write-once access to store the MLIR operation corresponding to
@@ -140,13 +140,10 @@ class ModuleImport {
140140
/// Imports `func` into the current module.
141141
LogicalResult processFunction(llvm::Function *func);
142142

143-
/// Converts function attributes of LLVM Function \p func
144-
/// into LLVM dialect attributes of LLVMFuncOp \p funcOp.
143+
/// Converts function attributes of LLVM Function `func` into LLVM dialect
144+
/// attributes of LLVMFuncOp `funcOp`.
145145
void processFunctionAttributes(llvm::Function *func, LLVMFuncOp funcOp);
146146

147-
/// Imports `globalVar` as a GlobalOp, creating it if it doesn't exist.
148-
GlobalOp processGlobal(llvm::GlobalVariable *globalVar);
149-
150147
/// Sets the fastmath flags attribute for the imported operation `op` given
151148
/// the original instruction `inst`. Asserts if the operation does not
152149
/// implement the fastmath interface.
@@ -165,6 +162,11 @@ class ModuleImport {
165162
constantInsertionOp = nullptr;
166163
}
167164

165+
/// Converts an LLVM global variable into an MLIR LLVM dialect global
166+
/// operation if a conversion exists. Otherwise, returns failure.
167+
LogicalResult convertGlobal(llvm::GlobalVariable *globalVar);
168+
/// Imports the magic globals "global_ctors" and "global_dtors".
169+
LogicalResult convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar);
168170
/// Returns personality of `func` as a FlatSymbolRefAttr.
169171
FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *func);
170172
/// Imports `bb` into `block`, which must be initially empty.
@@ -218,9 +220,6 @@ class ModuleImport {
218220
/// function entry block.
219221
FailureOr<Value> convertConstantExpr(llvm::Constant *constant);
220222

221-
/// Imports the magic globals "global_ctors" and "global_dtors".
222-
LogicalResult convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar);
223-
224223
/// Builder pointing at where the next instruction should be generated.
225224
OpBuilder builder;
226225
/// Block to insert the next constant into.
@@ -248,8 +247,6 @@ class ModuleImport {
248247
/// operations for all operations that return no result. All operations that
249248
/// return a result have a valueMapping entry instead.
250249
DenseMap<llvm::Instruction *, Operation *> noResultOpMapping;
251-
/// Uniquing map of GlobalVariables.
252-
DenseMap<llvm::GlobalVariable *, GlobalOp> globals;
253250
/// The stateful type translator (contains named structs).
254251
LLVM::TypeFromLLVMIRTranslator typeTranslator;
255252
/// Stateful debug information importer.

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,10 @@ LogicalResult ModuleImport::convertGlobals() {
338338
}
339339
continue;
340340
}
341-
342-
if (!processGlobal(&globalVar))
343-
return failure();
341+
if (failed(convertGlobal(&globalVar))) {
342+
return emitError(mlirModule.getLoc())
343+
<< "unhandled global variable " << diag(globalVar);
344+
}
344345
}
345346
return success();
346347
}
@@ -531,17 +532,13 @@ Attribute ModuleImport::getConstantAsAttr(llvm::Constant *value) {
531532
return nullptr;
532533
}
533534

534-
GlobalOp ModuleImport::processGlobal(llvm::GlobalVariable *globalVar) {
535-
if (globals.count(globalVar))
536-
return globals[globalVar];
537-
535+
LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
538536
// Insert the global after the last one or at the start of the module.
539537
OpBuilder::InsertionGuard guard(builder);
540-
if (!globalInsertionOp) {
538+
if (!globalInsertionOp)
541539
builder.setInsertionPointToStart(mlirModule.getBody());
542-
} else {
540+
else
543541
builder.setInsertionPointAfter(globalInsertionOp);
544-
}
545542

546543
Attribute valueAttr;
547544
if (globalVar->hasInitializer())
@@ -556,7 +553,7 @@ GlobalOp ModuleImport::processGlobal(llvm::GlobalVariable *globalVar) {
556553
}
557554

558555
GlobalOp globalOp = builder.create<GlobalOp>(
559-
UnknownLoc::get(context), type, globalVar->isConstant(),
556+
mlirModule.getLoc(), type, globalVar->isConstant(),
560557
convertLinkageFromLLVM(globalVar->getLinkage()), globalVar->getName(),
561558
valueAttr, alignment, /*addr_space=*/globalVar->getAddressSpace(),
562559
/*dso_local=*/globalVar->isDSOLocal(),
@@ -570,7 +567,7 @@ GlobalOp ModuleImport::processGlobal(llvm::GlobalVariable *globalVar) {
570567
FailureOr<Value> initializer =
571568
convertConstantExpr(globalVar->getInitializer());
572569
if (failed(initializer))
573-
return {};
570+
return failure();
574571
builder.create<ReturnOp>(globalOp.getLoc(), *initializer);
575572
}
576573
if (globalVar->hasAtLeastLocalUnnamedAddr()) {
@@ -580,7 +577,7 @@ GlobalOp ModuleImport::processGlobal(llvm::GlobalVariable *globalVar) {
580577
if (globalVar->hasSection())
581578
globalOp.setSection(globalVar->getSection());
582579

583-
return globals[globalVar] = globalOp;
580+
return success();
584581
}
585582

586583
LogicalResult
@@ -695,8 +692,9 @@ FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
695692

696693
// Convert global variable accesses.
697694
if (auto *globalVar = dyn_cast<llvm::GlobalVariable>(constant)) {
698-
return builder.create<AddressOfOp>(loc, processGlobal(globalVar))
699-
.getResult();
695+
Type type = convertType(globalVar->getType());
696+
auto symbolRef = FlatSymbolRefAttr::get(context, globalVar->getName());
697+
return builder.create<AddressOfOp>(loc, type, symbolRef).getResult();
700698
}
701699

702700
// Convert constant expressions.
@@ -771,11 +769,10 @@ FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
771769

772770
// Insert the constant after the last one or at the start or the entry block.
773771
OpBuilder::InsertionGuard guard(builder);
774-
if (!constantInsertionOp) {
772+
if (!constantInsertionOp)
775773
builder.setInsertionPointToStart(constantInsertionBlock);
776-
} else {
774+
else
777775
builder.setInsertionPointAfter(constantInsertionOp);
778-
}
779776

780777
// Convert all constants of the expression and add them to `valueMapping`.
781778
SetVector<llvm::Constant *> constantsToConvert =

mlir/test/Target/LLVMIR/Import/global-variables.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,18 @@
1212
; CHECK-SAME: {addr_space = 0 : i32, alignment = 8 : i64} : f64
1313
@global_float = external global double, align 8
1414

15+
; CHECK: llvm.mlir.global internal constant @address_before
16+
; CHECK: = llvm.mlir.addressof @global_int : !llvm.ptr<i32>
17+
@address_before = internal constant i32* @global_int
18+
1519
; CHECK: llvm.mlir.global external @global_int
1620
; CHECK-SAME: {addr_space = 0 : i32, alignment = 8 : i64} : i32
1721
@global_int = external global i32, align 8
1822

23+
; CHECK: llvm.mlir.global internal constant @address_after
24+
; CHECK: = llvm.mlir.addressof @global_int : !llvm.ptr<i32>
25+
@address_after = internal constant i32* @global_int
26+
1927
; CHECK: llvm.mlir.global internal @global_string("hello world")
2028
@global_string = internal global [11 x i8] c"hello world"
2129

mlir/test/Target/LLVMIR/Import/import-failure.ll

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ bb1:
2727

2828
; // -----
2929

30+
; CHECK: error: unhandled constant i8* blockaddress(@unhandled_global, %bb1)
31+
; CHECK: error: unhandled global variable @private = private global i8* blockaddress(@unhandled_global, %bb1)
32+
@private = private global i8* blockaddress(@unhandled_global, %bb1)
33+
34+
define void @unhandled_global() {
35+
bb1:
36+
ret void
37+
}
38+
39+
; // -----
40+
3041
declare void @llvm.gcroot(ptr %arg0, ptr %arg1)
3142

3243
; CHECK: error: unhandled intrinsic call void @llvm.gcroot(ptr %arg0, ptr %arg1)
@@ -63,7 +74,7 @@ define void @dropped_instruction(i64 %arg1) {
6374
!llvm.module.flags = !{!0}
6475
!0 = !{i32 2, !"Debug Info Version", i32 3}
6576
!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
66-
!2 = !DIFile(filename: "debug-info.ll", directory: "/")
77+
!2 = !DIFile(filename: "import-failure.ll", directory: "/")
6778
!3 = !DILocalVariable(scope: !4, name: "arg", file: !2, line: 1, arg: 1, align: 32);
6879
!4 = distinct !DISubprogram(name: "intrinsic", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1)
6980
!5 = !DILocation(line: 1, column: 2, scope: !4)

0 commit comments

Comments
 (0)