23#define GEN_PASS_DEF_ACCDECLARECTORDTORCONVERSION
24#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
32static void collectExistingGlobalCtors(
36 for (
auto globalCtors : mod.getOps<LLVM::GlobalCtorsOp>()) {
37 ctors.append(globalCtors.getCtors().begin(), globalCtors.getCtors().end());
38 for (
Attribute attr : globalCtors.getPriorities())
39 priorities.push_back(cast<IntegerAttr>(attr).getInt());
40 data.append(globalCtors.getData().begin(), globalCtors.getData().end());
41 globalCtorsOps.push_back(globalCtors);
45static void collectExistingGlobalDtors(
49 for (
auto globalDtors : mod.getOps<LLVM::GlobalDtorsOp>()) {
50 dtors.append(globalDtors.getDtors().begin(), globalDtors.getDtors().end());
51 for (
Attribute attr : globalDtors.getPriorities())
52 priorities.push_back(cast<IntegerAttr>(attr).getInt());
53 data.append(globalDtors.getData().begin(), globalDtors.getData().end());
54 globalDtorsOps.push_back(globalDtors);
58static void replaceGlobalCtors(ModuleOp mod,
OpBuilder &builder,
63 for (
auto globalCtors : oldOps)
69 LLVM::GlobalCtorsOp::create(
74static void replaceGlobalDtors(ModuleOp mod,
OpBuilder &builder,
79 for (
auto globalDtors : oldOps)
85 LLVM::GlobalDtorsOp::create(
92static LLVM::LLVMFuncOp createLLVMFunctionFromRegion(StringRef symName,
96 auto llvmVoidTy = LLVM::LLVMVoidType::get(mod.getContext());
97 auto funcTy = LLVM::LLVMFunctionType::get(llvmVoidTy, {},
false);
99 auto newFunc = LLVM::LLVMFuncOp::create(builder, mod.getLoc(), symName,
100 funcTy, LLVM::Linkage::Internal);
102 Block *entry = newFunc.addEntryBlock(builder);
114 LLVM::ReturnOp::create(builder, mod.getLoc(),
ValueRange{});
120struct ACCDeclareCtorDtorConversion
121 :
public acc::impl::ACCDeclareCtorDtorConversionBase<
122 ACCDeclareCtorDtorConversion> {
125 void runOnOperation()
override {
126 ModuleOp mod = getOperation();
127 OpBuilder builder{mod.getBodyRegion()};
128 SmallVector<Operation *> worklist;
130 SmallVector<Attribute, 8> allCtors;
131 SmallVector<int32_t, 8> ctorPriorities;
132 SmallVector<Attribute, 8> ctorData;
133 SmallVector<LLVM::GlobalCtorsOp, 4> globalCtorsOps;
134 collectExistingGlobalCtors(mod, allCtors, ctorPriorities, ctorData,
136 size_t existingCtorCount = allCtors.size();
138 SmallVector<Attribute, 8> allDtors;
139 SmallVector<int32_t, 8> dtorPriorities;
140 SmallVector<Attribute, 8> dtorData;
141 SmallVector<LLVM::GlobalDtorsOp, 4> globalDtorsOps;
142 collectExistingGlobalDtors(mod, allDtors, dtorPriorities, dtorData,
144 size_t existingDtorCount = allDtors.size();
146 mod.walk([&](acc::GlobalConstructorOp op) {
147 LLVM::LLVMFuncOp newCtor = createLLVMFunctionFromRegion(
148 op.getSymName(), op.getRegion(), mod, builder);
151 ctorPriorities.push_back(priority);
153 ctorData.push_back(LLVM::ZeroAttr::get(builder.
getContext()));
154 worklist.push_back(op.getOperation());
157 mod.walk([&](acc::GlobalDestructorOp op) {
159 LLVM::LLVMFuncOp newDtor = createLLVMFunctionFromRegion(
160 op.getSymName(), op.getRegion(), mod, builder);
163 dtorPriorities.push_back(priority);
165 dtorData.push_back(LLVM::ZeroAttr::get(builder.
getContext()));
167 worklist.push_back(op.getOperation());
170 if (allCtors.size() > existingCtorCount)
171 replaceGlobalCtors(mod, builder, allCtors, ctorPriorities, ctorData,
173 if (allDtors.size() > existingDtorCount)
174 replaceGlobalDtors(mod, builder, allDtors, dtorPriorities, dtorData,
177 for (Operation *op : worklist)
Attributes are known-constant values of operations.
Block represents an ordered list of Operations.
Operation * getTerminator()
Get the terminator operation of this block.
BlockArgListType getArguments()
ArrayAttr getI32ArrayAttr(ArrayRef< int32_t > values)
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
MLIRContext * getContext() const
static FlatSymbolRefAttr get(StringAttr value)
Construct a symbol reference for the given value name.
This is a utility class for mapping one set of IR entities to another.
void map(Value from, Value to)
Inserts a new mapping for 'from' to 'to'.
This class helps build Operations.
Operation * clone(Operation &op, IRMapping &mapper)
Creates a deep copy of the specified operation, remapping any operands that use values outside of the...
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
Operation is the basic unit of execution within MLIR.
result_range getResults()
void erase()
Remove this operation from its parent block and delete it.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class provides an abstraction over the different types of ranges over Values.
Include the generated interface declarations.