Skip to content

Commit 3086e55

Browse files
committed
[MLIR][LLVMIR] Add support for empty global ctor/dtor lists
1 parent 829e2a5 commit 3086e55

File tree

5 files changed

+79
-27
lines changed

5 files changed

+79
-27
lines changed

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,32 +1071,39 @@ LogicalResult
10711071
ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
10721072
if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
10731073
return failure();
1074-
auto *initializer =
1075-
dyn_cast<llvm::ConstantArray>(globalVar->getInitializer());
1076-
if (!initializer)
1074+
llvm::Constant *initializer = globalVar->getInitializer();
1075+
1076+
bool knownInit = isa<llvm::ConstantArray>(initializer) ||
1077+
isa<llvm::ConstantAggregateZero>(initializer);
1078+
if (!knownInit)
10771079
return failure();
10781080

10791081
SmallVector<Attribute> funcs;
10801082
SmallVector<int32_t> priorities;
1081-
for (llvm::Value *operand : initializer->operands()) {
1082-
auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
1083-
if (!aggregate || aggregate->getNumOperands() != 3)
1084-
return failure();
1083+
if (auto caInit = dyn_cast<llvm::ConstantArray>(initializer)) {
1084+
for (llvm::Value *operand : initializer->operands()) {
1085+
auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
1086+
if (!aggregate || aggregate->getNumOperands() != 3)
1087+
return failure();
10851088

1086-
auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
1087-
auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
1088-
auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
1089-
if (!priority || !func || !data)
1090-
return failure();
1089+
auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
1090+
auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
1091+
auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
1092+
if (!priority || !func || !data)
1093+
return failure();
10911094

1092-
// GlobalCtorsOps and GlobalDtorsOps do not support non-null data fields.
1093-
if (!data->isNullValue())
1094-
return failure();
1095+
// GlobalCtorsOps and GlobalDtorsOps do not support non-null data fields.
1096+
if (!data->isNullValue())
1097+
return failure();
10951098

1096-
funcs.push_back(FlatSymbolRefAttr::get(context, func->getName()));
1097-
priorities.push_back(priority->getValue().getZExtValue());
1099+
funcs.push_back(FlatSymbolRefAttr::get(context, func->getName()));
1100+
priorities.push_back(priority->getValue().getZExtValue());
1101+
}
10981102
}
10991103

1104+
// Note: no action needed for ConstantAggregateZero, which implies empty
1105+
// ctor/dtor lists.
1106+
11001107
// Insert the global after the last one or at the start of the module.
11011108
OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
11021109

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,16 +1258,37 @@ LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
12581258
auto dtorOp = dyn_cast<GlobalDtorsOp>(op);
12591259
if (!ctorOp && !dtorOp)
12601260
continue;
1261-
auto range = ctorOp ? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
1262-
: llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
1263-
auto appendGlobalFn =
1264-
ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
1265-
for (auto symbolAndPriority : range) {
1266-
llvm::Function *f = lookupFunction(
1267-
cast<FlatSymbolRefAttr>(std::get<0>(symbolAndPriority)).getValue());
1268-
appendGlobalFn(*llvmModule, f,
1269-
cast<IntegerAttr>(std::get<1>(symbolAndPriority)).getInt(),
1270-
/*Data=*/nullptr);
1261+
1262+
// The empty / zero initialized version of llvm.global_(c|d)tors cannot be
1263+
// handled by appendGlobalFn logic below, which just ignores empty (c|d)tor
1264+
// lists. Make sure it gets emitted.
1265+
if ((ctorOp && ctorOp.getCtors().empty()) ||
1266+
(dtorOp && dtorOp.getDtors().empty())) {
1267+
llvm::IRBuilder<llvm::TargetFolder> builder(
1268+
llvmModule->getContext(),
1269+
llvm::TargetFolder(llvmModule->getDataLayout()));
1270+
llvm::Type *eltTy = llvm::StructType::get(
1271+
builder.getInt32Ty(), builder.getPtrTy(), builder.getPtrTy());
1272+
llvm::ArrayType *at = llvm::ArrayType::get(eltTy, 0);
1273+
llvm::Constant *zeroInit = llvm::Constant::getNullValue(at);
1274+
(void)new llvm::GlobalVariable(
1275+
*llvmModule, zeroInit->getType(), false,
1276+
llvm::GlobalValue::AppendingLinkage, zeroInit,
1277+
ctorOp ? "llvm.global_ctors" : "llvm.global_dtors");
1278+
} else {
1279+
auto range = ctorOp
1280+
? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
1281+
: llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
1282+
auto appendGlobalFn =
1283+
ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
1284+
for (auto symbolAndPriority : range) {
1285+
llvm::Function *f = lookupFunction(
1286+
cast<FlatSymbolRefAttr>(std::get<0>(symbolAndPriority)).getValue());
1287+
appendGlobalFn(
1288+
*llvmModule, f,
1289+
cast<IntegerAttr>(std::get<1>(symbolAndPriority)).getInt(),
1290+
/*Data=*/nullptr);
1291+
}
12711292
}
12721293
}
12731294

mlir/test/Dialect/LLVMIR/global.mlir

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,14 @@ llvm.mlir.global_ctors { ctors = [@ctor], priorities = [0 : i32]}
233233

234234
// -----
235235

236+
// CHECK: llvm.mlir.global_ctors {ctors = [], priorities = []}
237+
llvm.mlir.global_ctors {ctors = [], priorities = []}
238+
239+
// CHECK: llvm.mlir.global_dtors {dtors = [], priorities = []}
240+
llvm.mlir.global_dtors {dtors = [], priorities = []}
241+
242+
// -----
243+
236244
llvm.func @dtor() {
237245
llvm.return
238246
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,14 @@ define void @bar() {
256256

257257
; // -----
258258

259+
; CHECK: llvm.mlir.global_ctors {ctors = [], priorities = []}
260+
@llvm.global_ctors = appending global [0 x { i32, ptr, ptr }] zeroinitializer
261+
262+
; CHECK: llvm.mlir.global_dtors {dtors = [], priorities = []}
263+
@llvm.global_dtors = appending global [0 x { i32, ptr, ptr }] zeroinitializer
264+
265+
; // -----
266+
259267
; Visibility attribute.
260268

261269
; CHECK: llvm.mlir.global external hidden constant @hidden("string")

mlir/test/Target/LLVMIR/llvmir.mlir

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,14 @@ llvm.func @foo() {
18591859

18601860
// -----
18611861

1862+
// CHECK: @llvm.global_ctors = appending global [0 x { i32, ptr, ptr }] zeroinitializer
1863+
llvm.mlir.global_ctors {ctors = [], priorities = []}
1864+
1865+
// CHECK: @llvm.global_dtors = appending global [0 x { i32, ptr, ptr }] zeroinitializer
1866+
llvm.mlir.global_dtors {dtors = [], priorities = []}
1867+
1868+
// -----
1869+
18621870
// CHECK: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @foo, ptr null }]
18631871
llvm.mlir.global_dtors { dtors = [@foo], priorities = [0 : i32]}
18641872

0 commit comments

Comments
 (0)