@@ -105,6 +105,8 @@ struct LoweringPreparePass : public LoweringPrepareBase<LoweringPreparePass> {
105105
106106 // / List of ctors and their priorities to be called before main()
107107 llvm::SmallVector<std::pair<std::string, uint32_t >, 4 > globalCtorList;
108+ // / List of dtors and their priorities to be called when unloading module.
109+ llvm::SmallVector<std::pair<std::string, uint32_t >, 4 > globalDtorList;
108110
109111 void setASTContext (clang::ASTContext *c) {
110112 astCtx = c;
@@ -823,10 +825,13 @@ void LoweringPreparePass::buildGlobalCtorDtorList() {
823825 mlir::ArrayAttr::get (&getContext (), globalCtors));
824826 }
825827
826- // We will eventual need to populate a global_dtor list, but that's not
827- // needed for globals with destructors. It will only be needed for functions
828- // that are marked as global destructors with an attribute.
829- assert (!cir::MissingFeatures::opGlobalDtorList ());
828+ if (!globalDtorList.empty ()) {
829+ llvm::SmallVector<mlir::Attribute> globalDtors =
830+ prepareCtorDtorAttrList<cir::GlobalDtorAttr>(&getContext (),
831+ globalDtorList);
832+ mlirModule->setAttr (cir::CIRDialect::getGlobalDtorsAttrName (),
833+ mlir::ArrayAttr::get (&getContext (), globalDtors));
834+ }
830835}
831836
832837void LoweringPreparePass::buildCXXGlobalInitFunc () {
@@ -975,22 +980,28 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor op) {
975980}
976981
977982void LoweringPreparePass::runOnOp (mlir::Operation *op) {
978- if (auto arrayCtor = dyn_cast<ArrayCtor>(op))
983+ if (auto arrayCtor = dyn_cast<cir:: ArrayCtor>(op)) {
979984 lowerArrayCtor (arrayCtor);
980- else if (auto arrayDtor = dyn_cast<cir::ArrayDtor>(op))
985+ } else if (auto arrayDtor = dyn_cast<cir::ArrayDtor>(op)) {
981986 lowerArrayDtor (arrayDtor);
982- else if (auto cast = mlir::dyn_cast<cir::CastOp>(op))
987+ } else if (auto cast = mlir::dyn_cast<cir::CastOp>(op)) {
983988 lowerCastOp (cast);
984- else if (auto complexDiv = mlir::dyn_cast<cir::ComplexDivOp>(op))
989+ } else if (auto complexDiv = mlir::dyn_cast<cir::ComplexDivOp>(op)) {
985990 lowerComplexDivOp (complexDiv);
986- else if (auto complexMul = mlir::dyn_cast<cir::ComplexMulOp>(op))
991+ } else if (auto complexMul = mlir::dyn_cast<cir::ComplexMulOp>(op)) {
987992 lowerComplexMulOp (complexMul);
988- else if (auto glob = mlir::dyn_cast<cir::GlobalOp>(op))
993+ } else if (auto glob = mlir::dyn_cast<cir::GlobalOp>(op)) {
989994 lowerGlobalOp (glob);
990- else if (auto dynamicCast = mlir::dyn_cast<cir::DynamicCastOp>(op))
995+ } else if (auto dynamicCast = mlir::dyn_cast<cir::DynamicCastOp>(op)) {
991996 lowerDynamicCastOp (dynamicCast);
992- else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op))
997+ } else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op)) {
993998 lowerUnaryOp (unary);
999+ } else if (auto fnOp = dyn_cast<cir::FuncOp>(op)) {
1000+ if (auto globalCtor = fnOp.getGlobalCtorPriority ())
1001+ globalCtorList.emplace_back (fnOp.getName (), globalCtor.value ());
1002+ else if (auto globalDtor = fnOp.getGlobalDtorPriority ())
1003+ globalDtorList.emplace_back (fnOp.getName (), globalDtor.value ());
1004+ }
9941005}
9951006
9961007void LoweringPreparePass::runOnOperation () {
@@ -1003,7 +1014,7 @@ void LoweringPreparePass::runOnOperation() {
10031014 op->walk ([&](mlir::Operation *op) {
10041015 if (mlir::isa<cir::ArrayCtor, cir::ArrayDtor, cir::CastOp,
10051016 cir::ComplexMulOp, cir::ComplexDivOp, cir::DynamicCastOp,
1006- cir::GlobalOp, cir::UnaryOp>(op))
1017+ cir::FuncOp, cir:: GlobalOp, cir::UnaryOp>(op))
10071018 opsToTransform.push_back (op);
10081019 });
10091020
0 commit comments