10#include "mlir/Dialect/Func/IR/FuncOps.h"
11#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
12#include "mlir/IR/PatternMatch.h"
13#include "mlir/Support/LogicalResult.h"
14#include "mlir/Transforms/DialectConversion.h"
15#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
19#include "llvm/Support/TimeProfiler.h"
25#define GEN_PASS_DEF_HOISTALLOCAS
26#include "clang/CIR/Dialect/Passes.h.inc"
31struct HoistAllocasPass :
public impl::HoistAllocasBase<HoistAllocasPass> {
33 HoistAllocasPass() =
default;
34 void runOnOperation()
override;
42static mlir::Block *getHoistDestBlock(cir::AllocaOp alloca) {
43 mlir::Region *region = alloca->getParentRegion();
45 mlir::Operation *parentOp = region->getParentOp();
49 if (parentOp->hasTrait<mlir::OpTrait::IsIsolatedFromAbove>() ||
50 mlir::isa<mlir::omp::OutlineableOpenMPOpInterface>(parentOp))
51 return ®ion->front();
52 region = parentOp->getParentRegion();
56static void process(mlir::ModuleOp mod, cir::FuncOp func) {
57 if (func.getRegion().empty())
61 llvm::DenseMap<mlir::Block *, mlir::Operation *> insertPoints;
65 func.getBody().walk<mlir::WalkOrder::PostOrder>([&](cir::AllocaOp alloca) {
66 mlir::Block *destBlock = getHoistDestBlock(alloca);
68 if (alloca.getDynAllocSize())
70 if (alloca->getBlock() == destBlock) {
78 if (std::all_of(destBlock->begin(), alloca->getIterator(),
79 [](mlir::Operation &blockOp) {
80 return blockOp.getNumRegions() == 0;
94 if (alloca.getConstant())
95 alloca.setConstant(
false);
100 mlir::Operation *&insertPoint = insertPoints[destBlock];
102 insertPoint = &*llvm::find_if(*destBlock, [](mlir::Operation &blockOp) {
103 return !mlir::isa<cir::AllocaOp>(blockOp);
105 alloca->moveBefore(insertPoint);
109void HoistAllocasPass::runOnOperation() {
110 llvm::TimeTraceScope scope(
"Hoist Allocas");
111 llvm::SmallVector<Operation *, 16> ops;
113 Operation *op = getOperation();
114 auto mod = mlir::dyn_cast<mlir::ModuleOp>(op);
116 mod = op->getParentOfType<mlir::ModuleOp>();
120 getOperation()->walk<mlir::WalkOrder::PreOrder>([&](cir::FuncOp op) {
122 return mlir::WalkResult::skip();
129 return std::make_unique<HoistAllocasPass>();
std::unique_ptr< Pass > createHoistAllocasPass()
static bool optInfoAttr()